AWS Fargate で実行したコンテナに固定のグローバルIPアドレスを割り当てる

## 概要
* AWS Fargate で起動したコンテナからあるサーバへの接続をIPアドレスで制限をかけたいが、普通にFargateを設定したコンテナでは、割り当てられるグローバルIPアドレスはコロコロ変わり固定ではない。
* AWS Fargate で VPC 内に作成されたコンテナからインターネットへ出るときに AWS NATゲートウェイを経由させることで、NATゲートウェイに割り当てたEIPがコンテナの接続元IPアドレスとして固定することができる。接続先のサーバではそのEIPを設定することでアクセス制限を行うことができるようになる。

## 構成概要
![スクリーンショット 2019-06-22 18.24.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/62992411-f6c3-d0fb-1d7d-1ffb64a0934c.png)

## 構成内容
* Amazon ECR
 * Dockerイメージレジストリ
 * ECR リポジトリの作成は、AWS CLI で行う
* Amazon Fargate
 * コンテナ実行環境
 * ECR からイメージを pull する
* VPC
 * Internetゲートウェイをアタッチする
 * Subnet-A と SubnetB を作成する
* Subnet-A
 * コンテナ用サブネット
 * ルートテーブルで、インターネットへの接続(0.0.0.0/0)を NATゲートウェイに向ける
* Subnet-B
 * NATゲートウェイ用サブネット
 * ルートテーブルで、インターネットへの接続(0.0.0.0/0)を Internetゲートウェイに向ける
* コンテナ
 * AWS ECR にある Docker イメージを AWS Fargate が PULL して、Subnet-A にコンテナ化する
* NAT ゲートウェイ
 * Elastic IP を割り当てる

## VPC環境設定概要
1. VPC作成
Internetゲートウェイをアタッチする

2. NATゲートウェイ用サブネット (Subnet-B) 作成
ルートテーブル設定
・インターネットへの接続(0.0.0.0/0)を Internetゲートウェイに向ける

3. Subnet-B 内に NATゲートウェイを作成
Elastic IP を割り当てる（今回は 3.113.58.14 ）

4. コンテナ用サブネット (Subnet-A) 作成
ルートテーブル設定
・インターネットへの接続(0.0.0.0/0)を NATゲートウェイに向ける

## 動作確認用コンテナのDockerイメージを作成
接続元IPアドレスを確認するために、コンテナ内から https://ifconfig.me にアクセスして接続元（コンテナ）のIPアドレスを確認する

1. Dockerfile 作成
<pre>
FROM alpine:latest
RUN apk --no-cache add curl
CMD curl -s https://ifconfig.me
</pre>
2. ビルド
<pre>
$ docker build -t demo .
</pre>
3. イメージ確認
<pre>
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
demo                latest              204b606e4331        33 minutes ago      6.92MB
alpine              latest              4d90542f0623        2 days ago          5.58MB
</pre>
4. 実行テスト
<pre>
$ docker run demo
xxx.xxx.xxx.xxx （接続元IPアドレス）
</pre>

## AWS ECR 設定概要
参考：[Dockerイメージを AWS ECR に登録して AWS ECS の Fargate でコンテナ化してサービス提供](https://qiita.com/tonishy/items/3b30092b12c3f47899f5)

1. AWS CLI で AWS ECR を設定するための IAM ユーザを作成
AmazonEC2ContainerRegistryFullAccessポリシーをアタッチする

2. 1.のIAMユーザをターミナルに登録する （今回は "ecr" というプロファイル名）
<pre>
$ aws configure --profile ecr
AWS Access Key ID [None]: **********
AWS Secret Access Key [None]: **********
Default region name [None]: ap-northeast-1
Default output format [None]:
</pre>

3. ECR のリポジトリを作成する （今回は "demo-repository" というリポジトリ名）
<pre>
$ aws ecr create-repository --repository-name demo-repository --profile ecr
</pre>

4. AWS ECR レジストリ用の docker login 認証コマンド文字列(12時間有効な認証トークン)を取得する
<pre>
$ aws ecr get-login --no-include-email --profile ecr
docker login -u AWS -p eyJwYXlsb2FkI〜

5. 上記で発行されたコマンドをそのまますべてをコピーして、ターミナルにペーストして実行する
<pre>
$ docker login -u AWS -p eyJwYXlsb2FkI〜
〜
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
</pre>

## Dockerイメージを AWS ECR へ PUSH する
1. Docker イメージにタグを付ける
<pre>
$ docker tag demo ＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repository:demo
</pre>
2. 確認
<pre>
$ docker images
REPOSITORY                                                          TAG                 IMAGE ID            CREATED             SIZE
＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repository   demo                204b606e4331        38 minutes ago      6.92MB
demo                                                                latest              204b606e4331        38 minutes ago      6.92MB
alpine                                                              latest              4d90542f0623        2 days ago          5.58MB
</pre>
3. Dockerイメージを AWS ECR に PUSH する
<pre>
$ docker push ＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repository:demo
The push refers to repository [777813037810.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repository]
39f660b1173d: Pushed
256a7af3acb1: Pushed
demo: digest: sha256:e903f0093f0d376a607c95279a204b36a15335dbda9fd0d73722f7593494aeff size: 738
</pre>

## AWS Fargate の設定とタスク実行
参考：[Dockerイメージを AWS ECR に登録して AWS ECS の Fargate でコンテナ化してサービス提供](https://qiita.com/tonishy/items/3b30092b12c3f47899f5)

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

(1) 新しいタスク定義の作成

|![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/3c1473ff-bd19-b676-3762-e18dac8c18d0.png)|
|:-:|

(2) 起動タイプで FARGATE を選択

|![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/1b9d144e-a940-ac1b-3bb8-2d4dd0d40607.png)|
|:-:|

(3) タスクとコンテナの定義の設定

①タスク定義名を ここでは demo-demo とする
　他はデフォルト

|![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/232124f7-af48-1437-d6ae-f4db63c9d2c9.png)|
|:-:|

②タスクの実行IAMロールはデフォルト

|![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/107b532b-1871-affc-a9a1-5da633a1058b.png)|
|:-:|

③タスクサイズは最小サイズで

|![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/afc7a5ba-993d-9ec8-2a56-bc01bce8084e.png)|
|:-:|

④コンテナの定義

コンテナの追加

|![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/7cf07cf3-34e7-ed58-6a97-45a848a83e54.png)|
|:-:|

コンテナ名： demo-container
イメージ： ＜AWSアカウントID＞.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repository:demo
他はデフォルト

|![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/1e5911b1-2fe5-cb40-f333-83207d564ca4.png)|
|:-:|

⑤作成

|![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/21ef7242-9030-7e23-6702-1aec08fd474b.png)|
|:-:|

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

(1) クラスターの作成

|![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/5074ead1-cdc7-a5fb-2bd2-193e2b79ca8e.png)|
|:-:|

(2) クラスターテンプレートの選択

「AWS Fargate を使用」 を選択

|![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/43819057-e15a-056b-1fa1-227011d40660.png)|
|:-:|

(3) クラスターの設定

クラスター名： demo-cluster
他はデフォルト

|![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/704652f2-4bac-e62a-4a38-32b7793d0267.png)|
|:-:|

(4) 作成

|![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/4e4dc4b8-ba64-e062-af6d-06118e47152f.png)|
|:-:|

### 3. タスク実行を作成する

① 新しいタスクの実行

|![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/7eecdac7-877d-7578-c829-dc5048d783ac.png)|
|:-:|

② タスクの実行

起動タイプ： FARGATE
タスク定義： demo-task:1
クラスター： demo-cluster
クラスターVPC
サブネット：コンテナ用に作成したサブネット
パブリックIPの自動割り当て： DISABLED

|![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/4d97ead5-e11d-9f18-30e0-efa689296eaf.png)|
|:-:|

③ タスクの実行
タスクを実行すると、コンテナのプロビジョニングが始まり、実行後に消滅する

|![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/522b1fa4-b8dc-307d-452b-183e64389129.png)|
|:-:|

### 4. タスクの実行結果の確認

タスクの実行結果は、CloudWatch ログ に送られる。
CloudWatchロググループは、タスク定義を作成した時に作られている。

CloudWatchロググループ: /ecs/demo-task
メッセージに Elastic IP の IPアドレスが表示されていれば成功。

|![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/c2275947-6e2d-0a88-6232-b578dea064fd.png)|
|:-:|