AWS CodeDeployでハマった話

CodeDeployは標準でblue/greenデプロイに対応している便利サービスですよね。 ソースリポジトリからの取得・配置やロールバックなどの実行がマネージドで作りこみが不要なのがいいところです。
そんなCodeDeployを試していてハマってしまったので備忘として残します。

やったこと

AWSCodeDeployでblue/greenデプロイメントをやってみた」を参考にCodeDeployのための準備をしました。 上記のサイトはblue/greenですが、今回はin-placeを試してみました。
一通り設定を終えて、マネコンからデプロイを実行してみるも失敗。。

失敗の詳細

事象

in-placeデプロイが失敗する。
デプロイの全てのステップがスキップされて何も処理されていない状態。

調査

「codedeploy-agent.log」に以下のエラーが出力されていた。
(/var/log/aws/codedeploy-agent/配下にCodeDeployエージェントが出力する実行ログです。)

2019-12-28 11:28:37 ERROR [codedeploy-agent(5462)]: InstanceAgent::Plugins::CodeDeployPlugin::CodeDeployControl: Error
 during certificate verification on codedeploy endpoint https://codedeploy-commands.ap-northeast-1.amazonaws.com

原因・対策

凡ミス・・・
CodeDeployのエンドポイントにNWアクセスできていないためでした。
今回のEC2インスタンスはプライベートセグメントに作成しており、所属しているサブネットにNATゲートウェイが設定されていませんでした。
EC2インスタンスをNATゲートウェイのあるサブネットに作り直し、NW的に疎通できる状態にしたところ、無事にデプロイが成功しました。

本エラーが出た時に疑った方がよい点

  • まずは何はともあれ、NWの設定
    CodeDeployエージェントがhttpsで外に出る必要があります
    (2019/1/4現在ではCodeDeployはエンドポイントに対応してない模様)

  • IAMロールが正しく設定されているか
    AWSCodeDeployでblue/greenデプロイメントをやってみた」のようにEC2側とCodeDeploy側のそれぞれで適切なIAMロールが設定されていればOK

  • CodeDeployエージェントが起動しているか
    以下のように"running"と出ればOK

# service codedepoloy-agent status
The AWS CodeDeploy agent is running as PID 2724

以上。

GitLabへのSSH接続でハマった話

新年あけましておめでとうございます。
IaCまわりの記事を読み漁っていたところコードが書きたくなり、GitLabを開設してみたのものの上手くSSH接続ができなかったので、解決方法を纏めます。
SSH接続するための設定手順は検索すればたくさん出てくるので詳細は割愛します。

やったこと

  1. GitLabにアカウントとProjectを作成
  2. クライアント端末側(Windows10)にGitBashをインストール
  3. GitBashにてsshキーペアを作成し、GitLabのSSH Keysに公開鍵を登録
    GitLabにSSHで接続するまでの手順 - Qiita」の手順を参考にさせていただきました。

が、しかし上手く接続できない

事象

一通り設定し終えてgit cloneしたところ、以下のエラーが発生してクローンできない。

$ git clone git@gitlab.com:wing.graces/my-sgc-project.git
Cloning into 'my-sgc-project'...
The authenticity of host 'gitlab.com (35.231.145.151)' can't be established.
ECDSA key fingerprint is SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitlab.com,35.231.145.151' (ECDSA) to the list of known hosts.
git@gitlab.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

SSHテストも同様にエラーが発生。
「Permission denied (publickey)」で接続できてないようです。

$ ssh -T git@gitlab.com
git@gitlab.com: Permission denied (publickey).

試したこと

configを見直す

~/.ssh/configの記述内容を見直しました。 特に問題なしでした。

Host gitlab   # sshで指定する任意の接続名
    HostName gitlab.com   # 接続先のホスト名またはIPアドレス
    IdentityFile ~/.ssh/rsa_gitlab   # 秘密鍵のパス
    User git   # 接続ユーザ(リモートURLアクセス時はgitで決め打ち)

GitLabのSSH Keysを見直す

作成した公開鍵が正しく登録されているか見直しました。
特に問題なしでした。

メールアドレスを指定してSSHキーペアを作り直す

Git - GitLabにssh接続しようとすると「Permission denied (publickey).」|teratail」を参考にGitLabのアカウント開設時に登録したメールアドレスを指定してSSHキーペアを作り直し、GitLabに再登録してみました。
コマンドは以下の通り、"-C"オプションをつけてssh-keygenを実行します。
実施後も特に事象は解消されず、接続できないままでした。

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/rsa_gitlab -C "GitLabの登録メールアドレス(ex: hoge@gmail.com)"

ssh-agentに秘密鍵を登録する

私の場合はこれで接続成功しました。
【GitLab】SSH接続をテストする - Qiita」を参考に、ssh-agentを起動し、作成した秘密鍵を登録します。

  • ssh-agentの秘密鍵の登録状態を確認
    ssh-agentが起動してない状態
$ ssh-add -l
Could not open a connection to your authentication agent.
  • ssh-agentを起動
$ eval `ssh-agent`
Agent pid 777
$ ssh-add -l
The agent has no identities.
$ ssh-add ~/.ssh/rsa_gitlab
Identity added: /c/Users/hoge/.ssh/rsa_gitlab (hoge@gmail.com)
  • SSH接続テストを実行
    以下のように「Welcome to GitLab」と出れば、無事に接続成功です!
    私の場合はこれでgit cloneも成功するようになりました。
$ ssh -T git@gitlab
Welcome to GitLab, @hoge!

コメント

以前、別の端末でGitBashでSSH接続の設定を行った際はssh-agentの設定なんてした覚えがないのですが・・
何となくですがデフォルト名でキーペアを作らなかったせいなのでしょうか?
とにかく接続には成功したので、そこはあまり深堀りしないことにします。

以上。

CSPO研修を受けた件

先月、CSPO (Certified Scrum Product Owner)研修を受けてきたので、その時のメモを書き残します。 ※個人的に気になったキーワードについて、ただただメモしておくだけなので、取り留めはありません。

CSPO研修とは?

講師の方

日本人とデンマーク人がタッグで研修を行ってくれました。

とても印象的なお二方でした。

サンダルとTシャツというラフなスタイルで、質問するとチョコレートを投げてくれたり。。笑

メモ

プロダクトバックログリファイメントミーティング

  • 次のスプリントに向けて、バックログの追加や並び替えを行う
  • DEVからもPOにFBする
  • チーム全員でバックログの見積もりを行う

価値駆動

  • インクリメンタル開発で少しずつつくる
  • 例えば、UI~DBスキーマを各層でサイロ的にしっかりとつくるのではなく、横串で必要最低限を少しずつつくる

スプリント期間の考え方

  • 日本は1週間がある
  • 日本以外はだいたい2週間
  • 1時間という考えの人もいる

プロダクトバックログ Ready

  • Top3のスプリントがReadyならReady Ready
  • 参考: ジェフ・サザーランド "Ready-Ready"

単体テスト

  • 単体テストはやめよう
  • UIテスト(エクスプロイトテスト)に時間を割くべき

完成の定義

障害リスト

  • 100個くらい書きだしてもよい

テストの網羅性

  • TDD will kill you
    • 要件を知らなくてもUTはできてしまう
  • POが出すテストケースがDEVが行うテストケース
  • テストカバレッジが正というのはウォーターフォールの概念
  • 優先すべきはプロダクトの要求と完了条件
  • 大事なのは今起きているバグを把握し、どういうプロセスでバグが再発しないようにするか!
  • 非企能もPBIとして積まれたものをこなす
    • PBIにのってこなければ、いつまでも対応されない

アジャイルへの投資

  • 銀行はリーンではないため難しい ⇒ Scrumはあきらめた
  • トヨタは経営層がリーンを理解しているため、できる
  • 製品の終了条件を明確化しておくことが大事 (Googleは45のサービスを殺した)

POチーム

  • プロダクトを説明するために何が必要かを考える

開発チーム

  • 1番大事なのは学ぶことができる人
  • 研修でチームが育ち、プロダクトの価値に繋がるとしたら、それはバックログに入れるべき

スクラムマスター

  • スクラムマスターはフルタイムで働くべき
  • DEVとの兼任はNG

SAFe is bullshit

Scrum Scaleが良くない理由

  • 個人と個人のやり取りホップ数が(大)
  • ハブとなるマネージャが入れ歯成り立つが結果、それは非スクラム化する

Value (価値)の定量評価

  • Business Value = 儲かる金額とか相対評価 (仮説)
  • ROI = Business Value / Complexity (Velocity)

タスクボード

  • スプリント内でチームで選択したPBIを任意の順序でデリバリーできる
  • スフォーミング「1つのPBIに群がって集中的に片付けること」を推奨
  • 手づまったり、1人作業になっていたら、SCMがもっと上手いやり方がないか聞く
  • ほとんどWIPで止まっている状態はよくない

レスポンシブデリバリー

  • 実利用環境のバグは前スプリントが完了していないことを意味する

デイリースクラムの目的

  • スプリントゴールの確認とリプラン
  • 残りの期間をどう使うか確認

スプリントゴール

  • DEVが自分たちで定めるのが望ましい

プロダクトバックログ

  • 必ずしもユーザーストーリーでなくてもい
  • ただ機能を書くだけでもよい

PBIの見積もり

  • 作業量はチームの言い値 ⇒ チームごとに比較できるものではない

ユーザーストーリー

  • 元々Featureと言われていた (本来は手書きのもの)
  • POが要件を明確化していくための対話ツール

【忘却のJavaScript#4】Vue.jsでガントチャートを表示してみる

やること

  • 前回使ったFullCalendarでDayGridとは別のタイプのカレンダーを表示させる
  • Timeline Viewというガントチャートが書けるライブラリを使ってみる

用意するもの

FullCalendarのインストール

> npm install --save @fullcalendar/resource-timeline

  • 以下のようなメッセージが出たら、インストール成功
・・・
+ @fullcalendar/resource-timeline@4.1.0
added 3 packages from 1 contributor and audited 43477 packages in 29.741s

Timeline.jsの作成

  • src\components配下にTimeline.vueを作成
  • 以下の通り、FullCalendarライブラリの読み込みと画面表示を実装

Timeline.vue:

<template>
  <!-- Timeline Viewを表示 -->
  <FullCalendar
    :schedulerLicenseKey="calendarCustomize.schedulerLicenseKey"
    :plugins="calendarCustomize.plugins"
    :defaultView="calendarCustomize.defaultView"
    :height="calendarCustomize.height"
    :resources="calendarCustomize.resources"
    :events="calendarCustomize.events"
    :slotDuration="calendarCustomize.slotDuration"
  />
</template>

<style lang="scss">
@import "~@fullcalendar/core/main.css";
@import "~@fullcalendar/timeline/main.css";
@import "~@fullcalendar/resource-timeline/main.css";
</style>

<script>
import FullCalendar from "@fullcalendar/vue";
import resourceTimelinePlugin from "@fullcalendar/resource-timeline";

export default {
  components: {
    FullCalendar // make the <FullCalendar> tag available
  },
  data() {
    return {
      calendarCustomize: {
        // ライセンス要求表示を非表示化
        schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
        // 使用するプラグイン
        plugins: [resourceTimelinePlugin],
        // 表示形式 (今回はTimeline View)
        defaultView: "resourceTimelineDay",
        // タイムラインの高さ (項目数に応じて自動調整)
        height: "auto",
        // 時間軸の表示幅 (今回は2時間ごと)
        slotDuration: { hours: 2 },
        // Resourcesのデモデータ
        resources:
          "https://fullcalendar.io/demo-resources.json?with-nesting&with-colors",
        // Resourcesごとのイベントのデモデータ
        events:
          "https://fullcalendar.io/demo-events.json?single-day&for-resource-timeline"
      }
    };
  }
};
</script>

router.jsの更新

カレンダーの表示

f:id:wingfair:20190516212149p:plain

【忘却のJavaScript #3】Vue.jsでカレンダーを表示してみる

やること

FullCalendarをVue.jsに取り込んで、カレンダーを表示させてみる

「FullCalendar」とは?

用意するもの

FullCalendarのインストール

  • コマンドプロンプトから以下のコマンドを実行し、ライブラリをインストールする
    • 今回は"daygrid"という卓上カレンダーによくあるタイプのカレンダーのライブラリを使ってみる
    • "core"と"vue"とはFullcalendarのメインコードとvue用のアダプタ
> npm install --save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid

  • 以下のようなメッセージが出たら、インストール成功
    • エラーが出る場合は後述の「npm installにてエラーが出る場合」を参照してみください
・・・
+ @fullcalendar/core@4.1.0
+ @fullcalendar/daygrid@4.1.0
+ @fullcalendar/vue@4.1.1
added 150 packages from 218 contributors, removed 52 packages, updated 1474 packages and audited 42927 packages in 128.145s

Sassのインストール

  • コマンドプロンプトから以下のコマンドを実行し、ライブラリをインストールする
    • ないとcssをインポートして、ビルドする際に怒られるので入れておく
> npm install sass-loader
> npm install node-sass

  • 以下のようなメッセージが出たら、インストール成功
・・・
+ sass-loader@7.1.0
added 10 packages from 17 contributors, updated 14 packages and audited 42949 packages in 48.009s
・・・
+ node-sass@4.12.0
added 58 packages from 58 contributors in 43.488s

Calendar.jsの作成

  • src\components配下にCalendar.vueを作成
  • 以下の通り、FullCalendarライブラリの読み込みと画面表示を実装

Calendar.vue:

<template>
  <FullCalendar defaultView="dayGridMonth" :plugins="calendarPlugins" />
</template>

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'

export default {
  components: {
    FullCalendar // make the <FullCalendar> tag available
  },
  data() {
    return {
      calendarPlugins: [ dayGridPlugin ]
    }
  }
};
</script>

router.jsの更新

  • src\router.jsにCalendar.vueへのリクエストパスを記述

router.vue:

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: "/calendar",
      name: "calendar",
      component: () => import("./components/Calendar")
    }
  ]
});

カレンダーの表示

f:id:wingfair:20190515235855p:plain
FullCalendarのDayGrid

npm installにてエラーが出る場合

"EPERM: operation not permitted"エラーが出る場合

エラー内容

以下のようなエラーが出てしまうことがある。
VSCodeでプロジェクトフォルダを開いていたせいか、ファイルを掴まれていて正常にインストールできていない模様。

npm ERR! Error: EPERM: operation not permitted, ・・・
対処

原因究明をしっかりやったわけではないので、あくまで私の場合はこうやったら解決できたという一例です。

  • VSCodeなどテキストエディタを開いている場合は一度閉じてから、npm installを再実行してみる
  • それでもエラーが出る場合は以下のコマンドでnpmのキャッシュを強制的にクリアしてから、npm installを再実行してみる
npm cache clean --force

  • それでもエラーが出る場合はOS再起動し、npm installを再実行してみる

"Maximum call stack size exceeded"エラーが出る場合

エラー内容

上記の"operation not permitted"を解消されても、以下のようなエラーが出てしまうことがある。
エラーメッセージ的には一度に実行できるシステムコールの回数を上限を超えている模様。

npm ERR! Maximum call stack size exceeded
対処

こちらも原因究明をしっかりやったわけではないので、あくまで私の場合はこうやったら解決したという一例です。

  • 以下のコマンドを実行後にnpm installを再実行
npm rebuild
npm install @vue/cli-service -D

  • vue/cli-service -Dを実行しているのは、cli-serviceが消えてしまっていたため
    • "npm cache clean --froce"の影響・・?

【忘却のJavaScript#2】Windows10でVue.js動かしてみる

Vue.jsをインストールして、動かしてみたいと思います。
今回はローカル環境をつくるところまでしかやりませんが、Web上にたくさん公開されている画面テンプレを利用すれば、かなり簡単にきれいな画面をつくることができる代物です。

「Vue.js」とは?

やりたいこと

yarnを使って、Windowsローカル環境にVue.jsをインストールし、サンプルページを表示させる

用意するもの

VSCodeインストール

  • 以下にアクセスし、「Download for Windows」を選択して、exeファイルをダウンロード
  • ダウンロード後、exeファイルを実行し、VSCodeをインストール
    • インストールウィザードでは全てデフォルト設定を選択
  • インストール完了後、起動してみて以下のような画面が立ち上げればOK

f:id:wingfair:20190513213959p:plain
VSCode起動後の画面

YARNインストール

  • 以下にアクセスし、「YARNをインストール」を押下
  • YARNの利用にはNode.jsが必要となるため、事前にインストールしておく
    • インストーラを使用する場合はまず Node.js をインストールしておく必要があります。」の"Node.js"をクリックするとダウンロード先に飛べる
    • 「10.15.3 LTS」を選択してmsiファイルをダウンロード
    • ダウンロード後、msiファイルを実行し、Node.jsをインストール
    • インストールウィザードでは全てデフォルト設定を選択
  • YARNのダウンロードページに戻り、[Windows]、[安定版1.16.0]を選択し、[インストーラをダウンロードする]を押下
  • ダウンロード後、msiファイルを実行し、YARNをインストール
  • インストールが完了したら、コマンドプロンプトから以下のコマンドを実行し、想定バージョンが表示されればOK
> yarn --version
1.16.0

Vue.jsインストール

> yarn global add @vue/cli

  • 以下のコマンドを実行し、想定バージョンがインストールされていることを確認する
> vue --version
3.7.0

プロジェクトの作成

> vue create sample-app

  • 上記、コマンド内でインタラクティブにプロジェクトの作成を行っていく
    • 状態管理やら静的解析やらテストやらプロジェクトで使うツールを選ぶのですが、詳細な説明は割愛・・
    • 今回はひとまず今後使いそうなものを以下の通り選択していく
      • Please pick a preset: ⇒ "Manually select features"
      • Check the features needed for your project:
        • (*) Babel
        • ( ) TypeScript
        • ( ) Progressive Web App (PWA) Support
        • (*) Router
        • (*) Vuex
        • ( ) CSS Pre-processors
        • (*) Linter / Formatter
        • (*) Unit Testing
        • (*) E2E Testing
        • (*) CSS Pre-processors
      • User history mode for router? ⇒ "n"
      • Pick a liner / formatter config: ⇒ "ESLint + Prettier"
      • Pick additional lint features: ⇒ "Lint on save"
      • Pick a unit testing solution: ⇒ "Jest"
      • Pick a E2E testing solution: ⇒ "Cypress (Chrome only)"
      • Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? ⇒ "In package.json"
      • Save this as a preset for future projects? ⇒ "y"
      • Save preset as: ⇒ "sample-app"
      • Pick the package manager to use when installing dependencies: ⇒ "Use Yarn"
    • 一通り選択してEnterを押下するとプロジェクト作成が開始される
      • 10分くらいかかる (Cypressが重い・・・)
  • プロジェクトをVSCodeから開いて確認してみる
    • VSCodeを起動し、[File]->[Open Folder...]を選択
    • ファイルエクスプローラから先ほど作成したプロジェクトのディレクトリを選択して開く
    • すると以下の画像のようにプロジェクトのディレクトリ階層が構築されていることを確認できる
      • 左側にプロジェクトのsrcやconfigが並んでいる
      • ちなみにHome.vueは後述しているWelcomeページの実態

f:id:wingfair:20190513224212p:plain
Vueプロジェクトの雛形

プロジェクトのビルドとアプリ起動

  • コマンドプロンプトから作成したプロジェクトディレクトリの第一階層に移動し、以下のコマンドを実行してビルド&起動を行う
    • 以下の通り、"DONE Compiled successfully"と"App running at"が表示されればOK
> yarn serve

DONE  Compiled successfully in 9367ms                                22:24:31

 App running at:
 - Local:   http://localhost:8080/
 - Network: http://192.168.10.9:8080/

 Note that the development build is not optimized.
 To create a production build, run yarn build.

  • 以下のURLにアクセスし、画像のように「Welcome to Your Vue.js App」のページが表示されれば成功

f:id:wingfair:20190513222755p:plain
Vueのウェルカムページ

以上。

JSON ServerでサクッとAPIモックサーバをつくってみる

直近でフロントエンドの開発に携わることになりました。
APIモックがあると何かと便利かと思い、ググったところJSON Serverなるものがあるということで試してみました。

JSON Server」とは?

JSON Server(ジェイソン サーバ)とは、JSONファイルを元にしてWebAPIサーバモックアップを作成できる簡易サーバです。
開発中のWebAPIテストなどに活用できます。

引用元: 「オープンソースのAPI連携/JSON Serverとは

やること

JSON Serverを構築し、GETリクエストでjsonデータを取得する

用意するもの

Node.jsインストール

リポジトリ追加

以下のコマンドを実行し、yumからNode.jsを落とせるようにリポジトリ追加する。

# curl -sL https://rpm.nodesource.com/setup_8.x | bash -

Node.jsインストール

以下のコマンドを実行し、Node.jsをインストールする。
(10分くらいかかる)

# yum install -y nodejs gcc-c++ make

JSON Serverインストール

以下のコマンドを実行し、JSON Serverをインストールする。
(10分くらいかかる)

# npm install -g json-server 

APIモック作成

作業用フォルダ作成

適当なパスに作業用フォルダを作成し、フォルダに移動する。
今回は/api-mockを切る。

# mkdir /api-mock
# cd /api-mock

JSON Serverが返すJSONデータの作成

今回は以下の通り人のリストを返すmemberlist.jsonをサンプルとして作成。

memberlist.json:

{
  "memberlist":[
   {
     "first_name":"太郎",
     "last_name":"田中",
     "jender":"男",
     "age":31
   },
   {
     "first_name":"花子",
     "last_name":"山田",
     "jender":"女",
     "age":27
   }
  ]
}

JSONファイルの中に書いた"memberlist"がリクエストパスとなる。

JSON Serverの起動

以下のコマンドを実行し、先ほど作成したJSONファイルをインプットにJSON Serverを起動する。
"--host"はJSON Server(192.168.10.4)のリクエストURLにIPアドレスを指定したい場合は使用。
"--host"がない場合はlocalhostを指定すればアクセス可能。

# json-server --host 192.168.10.4 memberlist.json


以下のように表示されれば、成功。
http://192.168.10.4:3000/memberlist"でGETリクエストを受け付けて、JSONを返す準備が整っている状態。

 \{^_^}/ hi!

  Loading memberlist.json
  Done

  Resources
  http://192.168.10.4:3000/memberlist

  Home
  http://192.168.10.4:3000

JSONファイルの更新を自動反映させたい場合は以下のように"--watch"を指定することで実現可能。

# json-server --watch memberlist.json

JSONデータの取得

リクエスト送信

Chromeを開き、以下のURLにアクセス
http://192.168.10.4:3000/memberlist

JSONデータ取得

以下の通り、無事に取得成功
これはお手軽で便利!

f:id:wingfair:20190508231738p:plain
GET結果

ローカル以外からJSON Serverにアクセスしたい場合

実はローカル以外の環境からこのAPIcurlで呼んでみたところ、エラーが発生した。

エラー内容

# curl http://192.168.10.4:3000/memberlist
curl: (7) Failed connect to 192.168.10.4:3000; 接続を拒否されました

原因

エラー文言でググったところ、以下の記事を発見。
普通にポートが開放されていなかっただけの模様。。

StackOverflow:
json-server cannot access via local IP

対策

以下のコマンドでfirewallのポート穴あけを実施

# firewall-cmd --zone=public --add-port=3000/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --list-all

これでちゃんと繋がるはずです。