AWS ECS Fargate ALBを設定する

# 初めに

以下を参考に Fargate で ALB を設定する手順を確認しました。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/create-application-load-balancer.html

# Docker イメージを作成する

この章は以下のドキュメントを参考にしています。

https://nodejs.org/ja/docs/guides/nodejs-docker-webapp/

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

Node.js をインストールします。

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install node
```

package.json ファイルを作成します。

```package.json
{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "First Last <first.last@example.com>",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  }
}
```

パッケージをインストールします。

```
npm install
```

service.js を作成します。

```js:service.js
'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
```

動作確認をします。

```
node server.js
```

Dockerfile を作成します。

```Dockerfile:Dockerfile
FROM node:12

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]
```

.dockerignore ファイルを作成します。

```:.dockerignore
node_modules
npm-debug.log
```

ビルドしてこのイメージを ECR にプッシュします。

```
docker build . -t test-user/node-web
```

# Fargate の設定

## クラスターを作成する

サービスで ECS を選択し、「クラスターの作成」をクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/2995067c-de80-980e-60e3-c2e895c02963.png)

「ネットワーキングのみ」を選択します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/644fef0c-2d53-1915-fdcb-a8d210c9fb1e.png)

「クラスター名」を入力し、「作成」をクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/d2cad36e-5edd-ddec-6a26-e696adbe1a74.png)

## タスク定義を作成する

左のナビゲーションペインから「タスク定義」を選択します。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/fb5ee087-4289-3109-678d-ac161d555f7f.png)

「新しいタスク定義の作成」をクリックします。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/c8b46a62-70e0-141a-ae73-642cbcd98ccf.png)

「Fargate」を選択します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/a6d86de4-c088-aae5-60af-00fb6cb18440.png)

タスク定義名を入力します。タスクロールは「なし」を選択します。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/3035e799-092b-4e9a-e6b4-b9714f41de9f.png)

初めてタスク定義を作成する場合はタスクの実行ロールは「新しいロールの作成」、2 回目以降であれば「ecsTaskExecutionRole」などのタスク実行ロールを選択します。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/d2e8c6a5-85ab-7d7a-62a7-9054938c13c3.png)

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/66d6501a-d909-044a-3c25-9a664770c50a.png)

タスクサイズを選択します。メモリは「0.5 GB」、vCPU は「0.25 vCPU」を選択します。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/6eddd292-9ea4-708b-188d-45c0a55ad020.png)

「コンテナの追加」をクリックします。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/910b67b0-bdc5-5ed4-ff7d-3da97583750f.png)

コンテナ名を入力し、イメージの入力部分に使用する ECR リポジトリの URI を貼り付けます。ポートはアプリケーションがリッスンするポート番号を入力します。その後、右下の「追加」をクリックします。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/acf6d690-8d13-fde6-0ea9-9e270dbad753.png)

コンテナの追加完了後、下までスクロールし「作成」をクリックします。

## ALB を作成する

サービスで EC2 を選択し、左のナビゲーションペインから「ロードバランサー」をクリックします。その後「ロードバランサーの作成」をクリックします。

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/42dbdc1c-7f38-fbe4-4441-3286224c4f44.png)

Application Load Balancer の「作成」をクリックします。

![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/8aff2d3f-de3a-e016-6b81-4a40f87f9940.png)

名前を入力し、スキームは「インターネット向け」を選択します。ロードバランサーのプロトコルは、今回は Fargate に ALB の設定をすることが目的なので HTTP を選択します。

![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/751ee4fe-76a1-0ab2-4066-c227ebfbab94.png)

アベイラビリティゾーンを選択します。

![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/90db75d6-f150-866c-42a0-a84c6d2ac48a.png)

セキュリティ設定の構成では、先ほどの設定で HTTPS が選択されていないので、以下のメッセージが表示されます。「次の手順」をクリックします。

![20.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/4cd4048c-1d8a-9f25-bfb0-61155e89cd32.png)

なお、HTTPS を選択している場合、ここで以下のようにサーバー証明書を選択します。

![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/05d6ef10-3d5f-6052-38b3-2017d0e2d0f5.png)

セキュリティポリシーは「ELBSecurityPolicy-2016-08」が推奨されています。

> 互換性のために ELBSecurityPolicy-2016-08 ポリシーをお勧めします。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies

セキュリティグループを選択します。

![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/0867f680-4de1-23fc-70b7-6bc088cf842a.png)

ターゲットグループを作成します。以下のドキュメントの注意に従ってターゲットの種類は IP を選択します。

> **重要**
>
> サービスのタスク定義で、awsvpc ネットワークモード (起動タイプが Fargate の場合に必要) が使用されている場合は、instance ではなく、ip をターゲットタイプとして選択する必要があります。これは、awsvpc ネットワークモードを使用するタスクは、Amazon EC2 インスタンスではなく、Elastic Network Interface に関連付けられているためです。

![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/b304502b-ba66-251b-a7cd-f702a345a5f1.png)

「次の手順」をクリックします。

![24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/84acefa5-b837-7dee-c7fc-cc2188cbf229.png)

何も設定せずに「次の手順」をクリックします。

![25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/1a4491c8-7278-499c-7712-80bbc1ecce59.png)

確認画面で設定を確認し、「作成」をクリックします。

## サービスを作成する

作成したクラスターを選択し、以下の「作成」をクリックします。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/e014d067-7163-d92b-a39b-4434ce4e1ceb.png)

サービスの設定は以下のように行います。

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/6863f2c7-ab2e-d468-b1fb-20636973c5c9.png)

デプロイメントは「ローリングアップデート」を選択し、「次のステップ」をクリックします。

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/bf0b08fb-3f53-e390-450c-6eca54a49d79.png)

VPC 、サブネット、セキュリティグループを選択します。パブリック IP の自動割り当ては「ENABLED」を選択します。パブリック IP の自動割り当てを「DISABLED」にすると、以下のエラーでイメージをプルできませんでした。

> ResourceInitializationError: unable to pull secrets or registry auth: pull command failed: : signal: killed

今回はパブリックサブネットでタスクを実行するので、以下に記述があるようにアウトバウンドネットワークのためにパブリック IP が必要です。

> パブリックサブネットで Fargate 起動タイプを使用してタスクを実行している場合は、タスクを起動する際、自動割り当てパブリック IP に [ENABLED] を選択します。これにより、イメージを取得するためのアウトバウンドネットワークアクセスをタスクに付与できます。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-pull-container-api-error-ecr/

なお、パブリック IP を使用しない場合は、エンドポイントを使用することでプルが可能になります。詳細は以下のドキュメントに記載されています。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/85b3b1e1-41ed-72c3-0010-6ef69c9650de.png)

「Application Load Balancer」を選択し、先ほど作成した ALB を選択します。

![26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/2df891fa-a41b-2fb4-2946-1589542d2521.png)

「ロードバランサーに追加」をクリックします。

![27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/20cf6d4c-6b26-b9c7-66f8-fe123c02af29.png)

作成したターゲットグループ名を選択します。その後、下までスクロールし「次のステップ」をクリックします。

![29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/a5a43fcd-58e2-73d8-cc9b-cbb3b71d157b.png)

「次のステップ」をクリックします。次の確認画面では「サービスの作成」をクリックします。

![30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/595ccdbf-fde2-60a1-af6f-7220d54c9328.png)

タスクのステータスが RUNNING に変わったら、以下の ALB の DNS 名をブラウザの URL 部分に張り付けます。

![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/4b90b4e5-77f6-3396-ee81-ea99611615a0.png)

以下のように表示されていることを確認します。

![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/886fa90a-13bd-813b-adfa-c01fb8ae6327.png)

以下のようにロードバランサーのターゲットグループに実行タスクが追加されていることが確認できます。

![36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/231a298e-4786-c21b-59ee-eeae5041fdff.png)

# 参考記事

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/create-application-load-balancer.html

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

https://nodejs.org/ja/docs/guides/nodejs-docker-webapp/

https://docs.npmjs.com/cli/v7/commands/npm-install

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies