ECR・ECSを使用して、Blue/Greenデプロイを行う

<h2>目次</h2>
<ol>
<li>背景</li>
<li>前提条件</li>
<li>ECSクラスターの作成</li>
<li>Blue/Greenデプロイに必要なリソースを作成</li>
<li>デプロイをしてみる</li>
</ol>
<h2>背景</h2>
<p><strong>前回記事</strong>
<a href="https://qiita.com/masa_skd30/items/bce4f8fbc5b6f14ea2b5">NuxtのアプリをDockerに移行して、ECRにプッシュするまで</a>  </p>
<p>とりあえず、ECRにプッシュするのはできましたよ～と。<br>
ECRにプッシュしたら、それをトリガーにして本番環境にも自動で反映される様にしたいなと。（ざっくり）<br>
色々調べてみたら、Blue/Greenデプロイっていうのが良さそうなのよね。  </p>
<blockquote>
<p>Blue-Green Deploymentは、検証環境をそのまま本番環境として利用することで、システムの停止時間を最小にするデプロイ手法です。 Blue-Green Deploymentをクラウドで実現するには、容易に検証環境を用意できることや、システムを簡単に切り替えられることが重要です。  </p>
</blockquote>
<p>うんうん、いいじゃん。<br>
これやってみよう。</p>
<h2>参考</h2>
<p><a href="https://qiita.com/kobayashi-m42/items/59cfe693670d930f7522">AWS FargateでBlue/Greenデプロイを行う</a>  </p>
<p>いつものごとく、先人たちの知恵に乗っかっていくパターン。  </p>
<h2>前提条件</h2>
<ol>
<li>ECRにリポジトリが作成されていること  </li>
<li>ECRにリポジトリにlatestタグがついたDockerメージがpushされていること  </li>
<li>ECSクラスターが作成されていること  </li>
</ol>
<p>1と2は、前回記事までの内容でOKですね。
っていうことで3の「ECSクラスターの作成」からやっていきます。</p>
<h2>ECSクラスターの作成</h2>
<p>マネジメントコンソールから「クラスターの作成」をクリックし、「ネットワーキングのみ」を選択。<br>
クラスター名はまあ適当につけます。<br>
「VPCを新しく作成する」みたいなチェックボックスがあるけど、VPCははるか昔に作ったのがあるので今回はチェックを入れません。<br>
TagsとかCloudWatch Container Insightsとかもとりあえずいいや…（面倒くさがり）  </p>
<p>名前しか決めていないけど、さっくりとクラスターは作成できました。  </p>
<h2>Blue/Greenデプロイに必要なリソースを作成</h2>
<h3>IAMロールの作成</h3>
<p>「AWSCodeDeployRoleForECS」という管理ポリシーをアタッチしたIAMロールを作成しました。  </p>
<h3>ALBの作成</h3>
<p>ALBは既にあるけど、テストもしたいから別で新しく作成しました。<br>
参考URLの中で「8080」にも許可しているのは、テスト用のポートとしてってことだね。<br>
とりあえず、ブルー用のターゲットグループだけ新規作成してFinish。</p>
<h3>タスクの定義の作成</h3>
<blockquote>
<p>Fargateのタスクの定義の作成方法については省略させていただきます。  </p>
</blockquote>
<p>省略されても困る！<br>
ってことで、とりあえず色々調べながらこんな感じに。  </p>
<p>ECSのコンソールから「新しいタスク定義の作成」をクリック。<br>
「起動タイプの互換性の選択」は「FARGATE」。<br>
タスク定義名はまあ適当に。<br>
タスクロールはさっき作ったIAMロール。<br>
タスクサイズは…現行のNuxtサーバーがt2.smallで動いているから、メモリ2GBの1vCPUにするよと。  </p>
<p>コンテナの追加から、<br>
コンテナ名はまあ適当に<br>
イメージはpushしたときのECRのレポジトリをペロッと張り付けて<br>
ポートマッピングについては、Dockerで使用しているPORTを選択。  </p>
<p>さくっとタスク定義が作成されました。</p>
<h3>ECSサービスの作成</h3>
<h4>サービスの設定</h4>
<p>起動タイプは「FARGATE」。<br>
タスク定義は一個前で作成したタスク定義。  </p>
<p>リビジョンは…デフォルトの表示だと「6 (latest)」になっているけど、これって7とか8がlatestになったら自動で変えてくれるんか…？<br>
なんかわからんけど、このままにしておく。  </p>
<p>サービス名は、例のごとく適当に。<br>
タスクの数は1にしておく。  </p>
<h4>デプロイメント</h4>
<p>「Blue/Green デプロイメント (AWS CodeDeploy を使用)」を選択。<br>
サービスロールは、さっき作ったIAMロールでいく。  </p>
<h4>VPC とセキュリティグループ</h4>
<p>クラスターVPC・サブネット・セキュリティグループは、Nuxtを動かしたい場所を選択。  </p>
<h4>ロードバランシング</h4>
<p>ALBにチェックを入れ、先ほど作成したALBを選択。  </p>
<h4>ロードバランス用のコンテナ</h4>
<p>デフォルトで、コンテナが選択されている。<br>
「ロードバランサーに追加」をクリック。  </p>
<p>プロダクションリスナーポート（たぶんメインで使用されるポート？）はHTTPS:443にして、<br>
テストリスナーポートはHTTP:&lt;テスト用ポート&gt;としました。  </p>
<h5>Additional configuration</h5>
<blockquote>
<p>ターゲットグループ1は、ALB作成時に作成したstg-fargate-blueを選択します。  </p>
</blockquote>
<p>なんでかわからんけど、ここは参考記事のままにはいかない。<br>
「新規作成」しか選べないのだ、なんかわからんけど。  </p>
<p>とりあえずHTTPで、パスパターンは「*」ヘルスチェックパスやらは「/」で乗り切る。  </p>
<h4>サービス作成実行</h4>
<p>ここまでの内容で、サービスを作成してみる。<br>
エラーはなし。<br>
気になるのは、ALBのルールが二つできちゃっていること。<br>
デフォルトルールはALB作成時に作られちゃったもので消せないし…<br>
一旦このままでいい…のか？  </p>
<h3>デプロイグループのデプロイ設定を変更</h3>
<blockquote>
<p>デプロイグループのデフォルトの設定では、デプロイされた際に、新しくデプロイが行われた側のターゲットグループに、トラフィックが自動で流れ始めてしまいます。<br>
今回は、動作確認をしてからターゲットグループの変更を行いたいため、トラフィックの再ルーティングするタイミングを指定します。今回は15分後に、再ルーティングされるように変更します。この設定をすることで、15分間待たなくても手動で再ルーティングすることも可能です。詳細は後述。</p>
<p>また、デフォルトの設定では、タスクの正常な展開後(再ルーティング後)1時間待ってから元のタスクが終了します。今回は30分後にタスクが終了するように設定を変更します。</p>
<p>デプロイグループを選択し、「編集」ボタンを押下することで、デプロイ設定画面が表示されます。</p>
</blockquote>
<p>なるほどね。<br>
こちらも15分と30分に設定しておく。</p>
<h2>デプロイをしてみる</h2>
<h3>現状確認</h3>
<p>443は通るが、テスト用ポートは通らない。
443はターゲットグループ1、テスト用ポートはターゲットグループ2に向いている。</p>
<h3>デプロイ実行</h3>
<p>まず、ECRにプッシュ。<br>
ECRのリポジトリ上に新しいイメージができていることを確認。  </p>
<p>ECSのサービスで「更新」を押し、「プラットフォームのバージョン」を「LATEST」にしてサービスの更新。<br>
「タスク」タブに2つのタスクが表示されていることを確認。<br>
443の方では変更前のものが、テスト用ポートの方では変更後のものが表示されることを確認。  </p>
<p>「デプロイ」タブからデプロイIDをクリックすると、デプロイ状況を確認できる画面に遷移する。<br>
「トラフィックの再ルーティング」をクリック。<br>
<strong>443の方でも、変更後のものが表示されることを確認。</strong><br>
443・テスト用ポートのどちらも、ターゲットグループ2に向いている。  </p>
<p>「元のタスクセットの終了」をクリック。<br>
<strong>443・テスト用ポートのどちらでも、引き続き変更後のものが表示されることを確認。</strong><br>
443・テスト用ポートのどちらも、ターゲットグループ2に向いている。  </p>
<p>テスト用ポートはこのまま見れて良いのか…？（テスト用ポートはターゲットグループ1に変わると思ってた）<br>
とりあえずもう一回やってたところ、同じ流れをたどって最終的には443・テスト用ポートどちらもターゲットグループ1になった。なるほどね～。  </p>
<h2>まとめ</h2>
<p>とりあえず、Blue/Greenデプロイはできたっぽい。<br>
あとはこれを自動化すれば…ってところでしょうか。</p>