AWS FargateをTerraformで構築する

re:Invent 2017にて、コンテナインスタンス要らずのコンテナマネジメントサービス(Fargate)がAWSから発表されたので、試してみます。
Terraformで、VPCから一気に作成していきます。
2018/2/15時点では東京リージョン未対応なので、バージニアリージョンで実行します。

##　作成後のイメージ（Fargate）

マネジメントコンソールでEC2が存在していないことを確認したいです。

![スクリーンショット 2017-12-16 時刻 20.21.11.png](https://qiita-image-store.s3.amazonaws.com/0/73176/af679849-01fd-0feb-5520-44ba1390c677.png)

##　以前のイメージ（ECS）

違いは、コンテナインスタンスの有無のみ
引き続きVPC/Subnet/ALB等のNetWork周りの設定は必須

![スクリーンショット 2017-12-16 時刻 20.30.39.png](https://qiita-image-store.s3.amazonaws.com/0/73176/3c7d9e59-f408-bf2a-855c-cfbd1158dac5.png)

## ECSのプロビジョニングファイルとの変更点

+ インスタンス設定が不要になったことにより、Auto Scale関連のファイル削除

+ Task定義

```:terrafrom
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  execution_role_arn       = "arn:aws:iam::${var.aws_id}:role/ecsAdminRole" #AWS標準ECS関連のポリシーAmazonECSTaskExecutionRolePolicy/AmazonECS_FullAccessを含む
  cpu                      = 256　#Fargate準拠の組み合わせのみ指定可能
  memory                   = 512　#Fargate準拠の組み合わせのみ指定可能
```

```task_definition.json
[
  {
    "name": "nginx",
    "image": "nginx:alpine",
    "cpu": 256, //必要に応じ変更
    "memory": 512, //必要に応じ変更
    "essential": true,
    "network_mode": "awsvpc", //追加 
    "portMappings": [
      {
        "containerPort": 80
      }
    ],
    "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
            "awslogs-group": "awslogs-${app_name}-nginx-log",
            "awslogs-region": "${aws_region}",
            "awslogs-stream-prefix": "awslogs-${app_name}-nginx"
        }
    }
  }
]
```

[CPU/Memoryの組み合わせはコチラ](https://aws.amazon.com/jp/blogs/news/aws-fargate/ "")

+ ALB Target Group

以下追加

```
   target_type = "ip"
```

+ ECS Service

IAM削除
NetWork設定をAuto Scaleから移管

```:diff
-  iam_role                           = "ecsServiceRole"
+  launch_type                        = "FARGATE"

+  launch_type = "FARGATE"
+
+  network_configuration {
+    subnets = [
+      "${aws_subnet.public-subnet1.id}",
+      "${aws_subnet.public-subnet2.id}"
+    ]
+
+    security_groups = [
+      "${aws_security_group.public_firewall.id}"
+    ]
+    assign_public_ip = "true"
+  }
```

## Terrafrom 実行

+ Terraformのバージョン

```
$ terraform --version
Terraform v0.11.3
+ provider.aws v1.9.0
+ provider.template v1.0.0
```

+ GitHub

https://github.com/Thirosue/terraform-sample/tree/master/aws_fargate

```:bush
## Dry Run
terraform plan -var 'aws_id=[AWS Account Idを記載]'

## apply
terraform apply -var 'aws_id=[AWS Account Idを記載]'

## 削除
terraform destroy -var 'aws_id=[AWS Account Idを記載]'
```

---------------------------------------
※追記（2018/02/15）：

`provider.aws v1.9.0`で`ECS Service`のパブリックIPの自動割り当て機能がサポートされたため、内容修正しました。

---------------------------------------

~~## CannotPullContainerError~~

~~applyは成功しますが、サービス登録したタスクが上がってきません。
エラー原因は、Docker ImageがPullできないようです。~~

~~原因は、`Auto-assign public IP`が`DISABLED`となっているため、インターネット接続が不可となっている模様。
(`provider.aws v1.6.0`では`Auto-assign public IP`は未対応　※2018/1/10時点）~~

~~## AWS CLIでネットワーク設定を調整~~

~~+ `ecs updatae-service`で`Auto-assign public IP`を`ENABLED`へ~~

~~タスクが`RUNNING`になりました。~~

```
# network-configurationでassignPublicIp=ENABLEDにupdate
$ aws ecs update-service \
  --cluster fargate-auth \
  --service fargate-auth-service \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxxxx,subnet-xxxxxx],securityGroups=[sg-xxxxxxx],assignPublicIp=ENABLED}"
```

## 最後に

コンテナインスタンスがマネジメントコンソール上存在しない事も無事確認できました。
[次回](https://qiita.com/takeshi_hirosue/items/79b8b4bc1941ee2ff5b0 "")は、オートスケールを試してみたいと思います。