ECSブルーグリーンデプロイメントをゼロから構築する。（その５：ECSとCodeDeployの作成）

# はじめに
前回はブルーグリーンデプロイ用の`ELB`とレコード作成を行いました。

ここまで長くかかりましたが、今回はブルーグリーンデプロイメントの設定としては最後となる`ECS`の各種設定を行っていこうと思います。

- 【前】[ECSブルーグリーンデプロイメントをゼロから構築する。（その４：ELBの作成とレコード作成）](https://qiita.com/sakai00kou/items/de8a788306bffdace3c1)
- 【次】[ECSブルーグリーンデプロイメントをゼロから構築する。（その６：ブルーグリーンデプロイの実行）](https://qiita.com/sakai00kou/items/df1725cfd8a63944e2a4)

# ECSの設定について
`ECS`にはクラスタ、サービス、タスクの概念があり、ブルーグリーンデプロイメントの設定を行うため、それぞれ設定を行う必要があります。

タスクは[その３](https://qiita.com/sakai00kou/items/fc51cead539f2917bfb6)で作成したタスク定義を使って起動したコンテナプロセスとなることから、ここで設定することは無いため、クラスタとサービスについて以下より作成していきます。

- [ECSクラスタの作成](#ecsクラスタの作成)
    - [ECSクラスタ初回作成時のエラー](#ecsクラスタ初回作成時のエラー)
- [ECSサービスの作成](#ecsサービスの作成)

## ECSクラスタの作成
「**Amazon Elastic Container Service**」ダッシュボードの「**クラスター**」→「**クラスターの作成**」でECSクラスタを以下のように作成します。

|項目|設定|備考|
|:--|:--|:--|
|クラスター名|blue-green-cluster|任意の名前を指定|
|デフォルトの名前空間|blue-green-cluster|任意の名前を指定|
|インフラストラクチャ|AWS Fargate(サーバーレス)|今回はFargateを指定|
|モニタリング|無効|今回はデフォルトのまま|
|タグ|空欄|今回はデフォルトのまま|

もし、ECSクラスタ作成時にエラーが発生した場合は以下「**ECSクラスタ初回作成時のエラー**」を参照してください。

### ECSクラスタ初回作成時のエラー
何かしらのECSクラスタを作成すると、裏で`CloudFormation`が動作して`AWSServiceRoleForECS`というIAMロールなどの必要リソースやECSクラスタが自動作成されますが、ECSクラスタが一度も作成されておらず、`AWSServiceRoleForECS`が存在しない場合、以下のようなエラーが発生します。

:::note alert
クラスター blue-green-cluster の作成中にエラーが発生しました。
Resource handler returned message: "Error occurred during operation 'CreateCluster SDK error: Service Unavailable. Please try again later. (Service: AmazonECS; Status Code: 500; Error Code: ServerException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; Proxy: null)'." (RequestToken: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, HandlerErrorCode: GeneralServiceException)
:::

再度同じECSクラスタ名で作成しようとしても、すでに存在するといったエラーが表示されてしまうため、上記のエラーが発生した場合は「**CloudFormation**」ダッシュボードの「**スタック**」→「**スタックの詳細**」より、「**ROLLBACK_COMPLETE**」となっている「**Infra-ECS-Cluster-[ECSクラスタ名]-xxxxxxxx**」というスタックを選択し、「**削除**」でスタックを削除します。

![Monosnap_20231112_160549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/3c181d2a-2e2a-583c-49d8-293a2142150c.png)

なお、上記`CloudFormation`のスタックを削除しても`AWSServiceRoleForECS`ロールは削除されないため、再度ECSクラスタを作成すればエラーにならずに作成できます。

## ECSサービスの作成
続いてECSサービスも作成していきます。

私の記憶では、2023年秋くらいまでは旧タイプのGUIコンソール形式に変えないとブルーグリーンデプロイメントの設定を行うことができませんでしたが、2023年11月現在では、新タイプのGUIコンソールでも設定できるようになっていたので、そのまま進めていきます。

作成したECSクラスタの画面の「**作成**」よりECSサービスを作成していきます。

![Monosnap_20231112_163324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/9f2ae90c-b167-ef3e-ffe0-3fc96857dfed.png)

項目が多いですが、以下のようにECSサービスを作成していきます。

|項目|設定|備考|
|:--|:--|:--|
|コンピューティングオプション|キャパシティープロバイダー戦略|今回はデフォルトのまま指定|
|キャパシティープロバイダー戦略|カスタムを使用(アドバンスト)||
|キャパシティープロバイダー|FARGATE|任意に指定|
|ベース|0|任意に指定|
|ウェイト|1|任意に指定|
|プラットフォームのバージョン|LATEST|
|アプリケーションタイプ|サービス|ブルーグリーンデプロイメント設定のためサービスを指定|
|リビジョンの手動指定|チェックなし||
|ファミリー|blue-green-test-taskdef|その３で作成したタスク定義を指定|
|リビジョン|1(最新)||
|サービス名|blue-green-service|任意の名前を指定|
|サービスタイプ|レプリカ||
|必要なタスク|1|今回はテストのため1を指定|
|デプロイタイプ|ブルー／グリーンデプロイ(AWS CodeDeployを使用)|デプロイオプションより指定|
|デプロイ設定|CodeDeployDefault.ECSAllAtOnce|任意のデプロイ設定を指定|
|CodeDeployのサービスロール|blue-green-test-role|その３で作成したIAMロールを指定|
|Service Connect|チェックなし|デフォルトのままチェックなし|
|サービス検出|チェックなし|デフォルトのままチェックなし|
|VPC|blue-green-vpc|その１で作成したVPCを指定|
|サブネット|blue-green-subnet-private1-ap-northeast-1a<br>blue-green-subnet-private2-ap-northeast-1c|その１で作成したプライベートサブネットを指定|
|セキュリティグループ|既存のセキュリティグループを使用|その３で作成したFargate用セキュリティグループを指定|
|セキュリティグループ名|blue-green-test-ecs-sg|その３で作成したFargate用セキュリティグループを指定|
|パブリックIP|オフ|今回はELB経由でFargateにアクセスするためオフとする|
|ロードバランサーの種類|Application Load Balancer||
|Application Load Balancer|既存のロードバランサーを使用||
|ロードバランサー|blue-green-elb|その４で作成したロードバランサーを指定|
|ヘルスチェックの猶予期間|0|今回は0のままとする|
|ロードバランス用のコンテナの選択|nginx 80:80||
|プロダクションリスナー|既存のリスナーを使用|作成済みのリスナー指定のため既存のリスナーを指定|
|プロダクションリスナー|443:HTTPS|作成済みのリスナーを指定|
|テストリスナーを追加|チェック|テストリスナーを作成するためチェック|
|テストリスナー|既存のリスナーを使用|作成済みのリスナー指定のため既存のリスナーを指定|
|テストリスナー|4430:HTTPS|作成済みのリスナーを指定|
|ターゲットグループ1|既存のターゲットグループを使用|作成済みのターゲットグループを指定|
|ターゲットグループ1名|blue-green-blue-tg||
|ターゲットグループ1ヘルスチェックパス|/index.html||
|ターゲットグループ1ヘルスチェックプロトコル|HTTP|
|ターゲットグループ2|既存のターゲットグループを使用|作成済みのターゲットグループを指定|
|ターゲットグループ2名|blue-green-green-tg||
|ターゲットグループ2ヘルスチェックパス|/index.html||
|ターゲットグループ2ヘルスチェックプロトコル|HTTP|
|サービスのオートスケーリングを使用|チェックなし|今回はテストのためチェックなし|
|Amazon ECSマネージドタグを有効にする|チェックする|デフォルトのままチェックあり|
|タグの伝播元|伝播しない|デフォルトのまま指定|

リスナー設定がややこしいので、以下リスナー設定部分のみ抜粋。

その４で設定したリスナールール設定でプロダクションリスナーとテストリスナー共に同じターゲットグループを指定していた場合、ECSサービスの作成に失敗するため、もし同じターゲットグループを指定していた場合は、リスナールールのターゲットグループ設定を修正してください。

![Monosnap_20231112_172835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/96177b13-1061-3bb4-56df-b3d07f430c3a.png)

なお、今回ブルーグリーンデプロイ用の設定を行うため、「**デプロイタイプ**」は「**ブルー／グリーンデプロイ**」を選択しましたが、デプロイタイプの設定は後から変更できないため、もし誤って「**ローリングアップデート**」を選択してしまった場合は、再度作り直しを行ってください。

無事正常に作成できれば以下のように表示されるため、ECSサービスがアクティブになることを確認します。

![Monosnap_20231112_173807.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/993c4ade-6c06-9db6-b298-8dc6fdee6137.png)

## CodeDeploy設定の確認
ECSサービスのデプロイタイプをブルーグリーンデプロイで作成した場合、ブルーグリーンデプロイメント用の`CodeDeploy`アプリケーションが自動的に作成されます。

「**CodeDeploy**」ダッシュボードの「**デプロイ・CodeDeploy**」→「**アプリケーション**」に`AppECS-[ECSクラスタ名]-[ECSサービス名]`のように作成されていることを確認します。

![Monosnap_20231112_174520.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/ef617f92-0c14-7593-94df-262f554b2571.png)

もし自動作成される`CodeDeploy`アプリケーションではなく、自分で名前を指定して作成したい場合は以下を参照してください。

### CodeDeployの名前を手動で設定する場合
:::note info
CodeDeployアプリケーション名を手動で設定したい場合に実施してください。
:::
自動作成される`CodeDeploy`アプリケーションは名前を指定したり修正することができないため、任意の名前を指定するためには、`CloudFormation`や`terraform`等の`IaC`ツールでコーディングして作成するか、自動作成される`CodeDeploy`アプリケーションを一度削除して、再度手動で作成する必要があります。

「**CodeDeploy**」ダッシュボードの「**デプロイ・CodeDeploy**」→「**アプリケーション**」より、自動作成のアプリケーション名を選択し、「**アプリケーションの削除**」で削除します。

![Monosnap_20231112_175232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/446485f7-77bd-db75-b84d-4d16da67eb64.png)

削除後、「**アプリケーションの作成**」より以下のように`CodeDeploy`アプリケーションを作成します。

|項目|設定|備考|
|:--|:--|:--|
|アプリケーション名|blue-green-deploy-app|任意の名前を指定|
|コンピューティングプラットフォーム|Amazon ECS|ブルーグリーンデプロイメントのためECSを指定|
|タグ|空欄|今回は未指定|

続いて「**デプロイグループの作成**」から以下のようにデプロイグループを手動で作成します。

|項目|設定|備考|
|:--|:--|:--|
|デプロイグループ名の入力|blue-green-deploy-group|任意の名前を指定|
|サービスロールの入力|blue-green-test-role|その３で作成したIAMロールを指定|
|ECSクラスター名を選択します|blue-green-cluster|先程作成したECSクラスタ名を指定|
|ECSサービス名を選択します|blue-green-service|先程作成したECSサービス名を指定|
|Load balancerを選択|blue-green-elb|その４で作成したロードバランサーを指定|
|本稼働リスナーポート|HTTPS:443|その４で作成した本稼働リスナーポートを指定|
|テストリスナーポート|HTTPS:4430|その４で作成したテストリスナーポートを指定|
|ターゲットグループ１の名前|blue-green-blue-tg|それぞれ別々のターゲットグループを指定|
|ターゲットグループ２の名前|blue-green-green-tg|それぞれ別々のターゲットグループを指定|
|トラフィックの再ルーティング|すぐにトラフィックを再ルーティング|今回はデフォルトのままとする|
|デプロイ設定|CodeDeployDefault.ECSAllAtOnce|今回はデフォルトのままとする|
|元のリビジョンの終了|※デフォルトのまま|今回はデフォルトのままとする|
|詳細|※デフォルトのまま|今回はデフォルトのままとする|

# おわりに
５回にわたり設定を行ってきたブルーグリーンデプロイメントですが、今回で設定としては完了となります。

次回はブルーグリーンデプロイ動作の確認や外部からのアクセスを試してみようと思います。