ECSブルーグリーンデプロイメントをゼロから構築する。（その３：事前準備、コンテナイメージ作成）

# はじめに
前回はブルーグリーンデプロイメントの設定を行う前の準備として、外部からアクセスする際に必要となるドメインの登録と証明書の発行を行いました。

今回も準備作業の続きとして、`Fargate`で使用するコンテナイメージの作成や、次回以降の設定で必要となるセキュリティグループやIAMロールの作成を行おうと思います。

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

# コンテナイメージの準備
次回以降の準備のため、`Fargate`実行に必要となるコンテナイメージやリポジトリ、タスク定義等の準備を行っていきます。

- [ECRリポジトリの作成](#ecrリポジトリの作成)
- [Dockerfileの準備](#dockerfileの準備)
- [ECRリポジトリへのプッシュ](#ecrリポジトリへのプッシュ)
- [イメージURIの確認](#イメージuriの確認)

## ECRリポジトリの作成
`Fargate`のコンテナイメージを格納する`ECR`リポジトリを作成します。

「**Amazon Elastic Container Service**」のダッシュボードより、「**Amazon ECR**」を選択し、「**Repositories**」→「**Private**」タブを選択、「**リポジトリを作成**」で作成するリポジトリの設定を行います。

今回は以下表のように設定を行い、リポジトリを作成しました。

|項目|設定|備考|
|:--|:--|:--|
|可視性設定|プライベート||
|リポジトリ名|blue-green-test|今回はblue-green-testという名前を指定|
|タグのイミュータビリティ|無効|デフォルトのまま|
|プッシュ時にスキャン|無効|デフォルトのまま|
|KMS暗号化|無効|デフォルトのまま|

## Dockerfileの準備
`Fargate`で動作させるコンテナイメージを作成していきます。

`Fargate`起動時に`Docker Hub`等から直接持ってくるようにしても良いのですが、おそらく自分の`AWS`アカウントの`ECR`リポジトリから起動するほうが実運用に近いかと思うので、適当なコンテナイメージを作成して、`ECR`リポジトリに格納するようにします。

今回は外部からWebアクセス確認できるよう`Nginx`の公式イメージを使い、適当な`index.html`ファイルを仕込んだカスタムイメージを作成しようと思います。

以下`index.html`と`Dockerfile`は同じ階層に作成してください。

```html:index.html
<h1>Hello World!</h1>
```

```dockerfile:Dockerfile
FROM --platform=linux/amd64 nginx:latest
RUN service nginx start
COPY index.html /usr/share/nginx/html
VOLUME /usr/share/nginx/html
```

なお、筆者の環境は`M2`搭載`Mac`を使用しているため、そのままビルドすると`ARM`形式でビルドされてしまうことから、上記`Dockerfile`で`--platform=linux/amd64`を指定してビルド形式を変えていますが、`Intel CPU`を使用しているようであれば`--platform=linux/amd64`の指定はなくても問題ありません。

## ECRリポジトリへのプッシュ
準備した`Dockerfile`をビルドして`ECR`にプッシュしていきます。

今回は自分のPC上で`Dockerfile`をビルドして`ECR`にプッシュするやり方としているので、もし自分のPC上で`docker`コマンドが実行できるようになっていなければ、`Docker Desktop`をインストールするなどして、`docker`コマンドが実行できるようにしておいてください。

ビルドからプッシュまでの手順については、`ECR`リポジトリ画面から、作成済みの`ECR`リポジトリを選択→「**プッシュコマンドの表示**」を選択することで確認することができます。

![Monosnap_20231104_181255.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/a15c7e12-808a-4f52-bdbf-0768eb6df872.png)

「**プッシュコマンドの表示**」を選択することで、以下のようなコマンド例が表示されるため、ターミナルで先程作成した`Dockerfile`、`index.html`ファイルが格納されている場所に移動して、そのままコピペで順番に実行すれば`ECR`リポジトリにコンテナイメージがプッシュされます。

![Monosnap_20231104_181700.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/d7cf4eda-febf-58d5-fa55-d60967882fc1.png)

以下のようにコンテナイメージが`ECR`リポジトリにプッシュされればOKです。

![Monosnap_20231104_182108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/25ee9fc5-2dba-c57e-5ee4-8cbbc31ec0ab.png)

## イメージURIの確認
プッシュしたコンテナイメージの詳細を確認し、後ほど使用するURIを確認しておきます。

`ECR`リポジトリには`latest`のイメージタグのコンテナイメージがプッシュされているはずなので、`latest`を選択し、詳細画面より「**URI**」を控えておきます。

![Monosnap_20231105_081822.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/965f7672-eb60-106a-3e4a-d729ed775251.png)

# Fargate用タスク定義の作成
`Fargate`を起動する際に必要となるタスク定義を予め作成しておきます。

「**Amazon Elastic Container Service**」ダッシュボードより、「**タスク定義**」→「**新しいタスク定義の作成**」→「**新しいタスク定義の作成**」を選択します。

![Monosnap_20231105_080203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/4c4411c8-fb41-3a2c-e85f-bfb19cf26964.png)

タスク定義とは`Docker`で言うところの`Docker-Compose`ファイルにあたる設定となり、起動するコンテナの情報やリソースの割り当て等を設定しておくことで、`ECS`、`Fargate`を起動する際にタスク定義に記載されている内容に沿ってコンテナが起動される定義となります。

項目が多いため、今回は入力した箇所のみ以下に記載します。

その他項目についてはデフォルト値が設定されているものとして進めてください。

- タスク定義の設定

|項目|設定|備考|
|:--|:--|:--|
|タスク定義ファミリー|blue-green-test-taskdef|任意の名前を設定|

- インフラストラクチャの要件

|項目|設定|備考|
|:--|:--|:--|
|起動タイプ|AWS Fargate|今回はFargateを指定|
|オペレーティングシステム/アーキテクチャ|Linux/X86_64||
|タスクサイズ CPU|.25 vCPU|今回はテストなので最小のリソースを割り当て|
|タスクサイズ メモリ|.5 GB|今回はテストなので最小のリソースを割り当て|
|タスクロール|-|デフォルトのまま未指定|
|タスク実行ロール|新しいロールの作成|事前に作成しておくこともできるが、今回は自動作成する|

- コンテナ - 1

|項目|設定|備考|
|:--|:--|:--|
|名前|nginx|任意の名前を設定|
|イメージURI|xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/blue-green-test:latest|先ほど控えたイメージURIを入力|
|コンテナポート|80||
|プロトコル|TCP||
|ポート名|nginx-80-tcp|今回はデフォルトのまま設定|
|アプリケーションプロトコル|HTTP||

# セキュリティグループの準備
次回以降の手順で使用する、`ELB`と`Fargate`で使用するセキュリティグループを予め作成しておきます。

今回の構成として、`HTTPS`による暗号化は`ELB`で終端するようにして、`Fargate`には暗号化なしの`HTTP`でアクセスするものとし、`Fargate`へのアクセスは`ELB`からのアクセスに限定しようと思います。

![security_group構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/a586a64a-b966-7b6e-2365-d1ac0a882ee7.png)

- [ELB側セキュリティグループの設定](#elb側セキュリティグループの設定)
- [Fargate側セキュリティグループの設定](#fargate側セキュリティグループの設定)

## ELB側セキュリティグループの設定
`ELB`側で使用するセキュリティグループについては、本番用アクセスを受け付ける443番ポートへのアクセスと、テスト用アクセスを受け付ける4430番ポートへのアクセスが受け付けられるようにインバウンドルールを設定します。

:::note info
今回はテスト用アクセスを4430番としましたが、環境により任意のポート番号を指定してください。
:::

「**VPC**」ダッシュボードより、「**Security groups**」→「**セキュリティグループを作成**」で以下のように設定します。

- 基本的な詳細

|項目|設定|備考|
|:--|:--|:--|
|セキュリティグループ名|blue-green-test-elb-sg|任意の名前を指定|
|説明|blue-green-test-elb-sg|任意の名前を指定|
|VPC|blue-green-vpc|その１で作成済みのVPCを選択|

- インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明|
|:--|:--|:--|:--|:--|
|HTTPS|TCP|443|0.0.0.0/0|空欄|
|カスタムTCP|TCP|4430|0.0.0.0/0|空欄|

- アウトバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明|
|:--|:--|:--|:--|:--|
|すべてのトラフィック|すべて|すべて|0.0.0.0/0|空欄|

- タグ

|キー|値|
|:--|:--|
|Name|blue-green-test-elb-sg|

## Fargate側セキュリティグループの設定
`Fargate`側で使用するセキュリティグループについては、`ELB`からのアクセスのみに制限した上で、`HTTP`ポートへのアクセスを受け付ける設定を行います。

`ELB`からのアクセスのみに制限する場合、`ELB`用で設定しているセキュリティグループの「**セキュリティグループID**」を指定することで、指定したセキュリティグループIDからのアクセス→つまり`ELB`からのアクセスに限定することができます。

- 基本的な詳細

|項目|設定|備考|
|:--|:--|:--|
|セキュリティグループ名|blue-green-test-ecs-sg|任意の名前を指定|
|説明|blue-green-test-ecs-sg|任意の名前を指定|
|VPC|blue-green-vpc|その１で作成済みのVPCを選択|

- インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明|
|:--|:--|:--|:--|:--|
|HTTP|TCP|80|※`blue-green-test-elb-sg`のセキュリティグループID|空欄|


- アウトバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明|
|:--|:--|:--|:--|:--|
|すべてのトラフィック|すべて|すべて|0.0.0.0/0|空欄|

- タグ

|キー|値|
|:--|:--|
|Name|blue-green-test-ecs-sg|

# IAMロールの準備
`CodeDeploy`から`ECS`の操作を行うために必要となるIAMロールを予め作成しておきます。

「**Identity and Access Management (IAM)**」のダッシュボードより、「**ロール**」→「**ロールを作成**」で以下のように選択することで`ECS`ブルーグリーンデプロイを実行するために必要となるポリシーが割り当てられたロールを作成することができるので、画面に沿って進めていきます。

![Monosnap_20231104_185455.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/9905ceff-6e88-7815-70ce-355c01f096cb.png)

なお、今回は以下のようなIAMロールを作成しました。

|項目|設定|備考|
|:--|:--|:--|
|信頼されたエンティティタイプ|AWSのサービス||
|サービスまたはユースケース|CodeDeploy|CodeDeployで使用するIAMロールとなるため、CodeDeployを選択|
|ユースケース|CodeDeploy - ECS|ECSブルーグリーンデプロイで使用するため、左記を選択|
|許可ポリシー|AWSCodeDeployRoleForECS|ユースケースに合わせて自動でポリシーが付与される<br>この画面では編集不可なので、ポリシーの追加等行いたい場合は作成後に修正する|
|許可の境界を設定|許可の境界なしでロールを作成|今回はデフォルトのまま|
|ロール名|blue-green-test-role|任意の名前を指定|
|説明|※デフォルトのまま|今回はデフォルトのまま|
|タグ|空欄|今回はデフォルトのまま|

# おわりに
今回はブルーグリーンデプロイメントの設定を行う前の準備として、ブルーグリーンデプロイメントの設定を行う際に必要となるIAMロールやコンテナイメージの作成を行いました。

次回はロードバランサーやターゲットグループの設定を行おうと思います。