ecs-cliでハマった件

手が空いたのでecs-cliでもやってみようと[チュートリアル](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-cli-tutorial-fargate.html)を試してみたら、ハマったのでメモ。

### やりたいこと
- ecs-cliでFargateクラスターとサービスを立ち上げる。

### ハマったこと
- タスクを上げる最後の最後のところで失敗する。

ecs-cliでFargateクラスターを立ち上げ、タスク定義を投入してサービスを立ち上げるというのが大まかなチュートリアルの流れなのだが、この最後のコマンドが失敗する。

```zsh
% ecs-cli compose --project-name myFargateSvc service up
INFO[0005] Using ECS task definition                     TaskDefinition="myFargateSvc:2"
INFO[0005] Auto-enabling ECS Managed Tags
INFO[0011] (service myFargateSvc) has started 1 tasks: (task 610ec5cbc7f346569f9f1d42ec37497a).  timestamp="2020-06-09 02:48:02 +0000 UTC"
INFO[0257] (service myFargateSvc) has started 1 tasks: (task 8de67ade75754c58a4d44b47ab712c09).  timestamp="2020-06-09 02:52:10 +0000 UTC"
INFO[0308] Created an ECS service                        service=myFargateSvc taskDefinition="myFargateSvc:2"
FATA[0308] Deployment has not completed: Running count has not changed for 5.00 minutes
```

コンソールを見ると、どうやらタイムアウトエラーで起動に失敗している模様。
<img width="1739" alt="スクリーンショット 2020-06-09 11.50.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/a6e7e4b8-80fe-ad56-cd8d-3006329dd594.png">
<img width="1750" alt="スクリーンショット 2020-06-09 11.54.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/e081a251-a36d-6903-6de4-aea310404008.png">
<img width="1709" alt="スクリーンショット 2020-06-09 12.05.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/a8baa3a0-290f-2834-ee86-434106682d45.png">

直接の原因はこれらしい。

```
DockerTimeoutError: Could not transition to started; timed out after waiting 3m0s
```

### 切り分け開始

詳しいログでも出てないかと、まずはタスクからログを送っている先であるCloudWatch Logs（awslogs）を見てみるも、空のまま。ただし、ロググループまでは作成されている。ロググループだけがない状態。

<img width="1146" alt="スクリーンショット 2020-06-09 11.48.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/f0aeb758-8689-8be6-6bb5-de9cf58290c6.png">

タスク定義（`docker-compose.yml`）もECS定義（`ecs-params.yml`）も間違っているようには見えない。そもそもそんなに複雑なことはしていない。
一体何が原因だ。。。


```dockerfile:docker-compose.yml
version: '3'
services:
  web:
    image: amazon/amazon-ecs-sample
    ports:
      - "80:80"
    logging:
      driver: awslogs
      options:
        awslogs-group: /ecs/myFargate0609
        awslogs-region: ap-northeast-1
        awslogs-stream-prefix: web
```

```yaml:ecs-params.yml
version: 1
task_definition:
  task_execution_role: ecsTaskExecutionRole
  ecs_network_mode: awsvpc
  task_size:
    mem_limit: 0.5GB
    cpu_limit: 256
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
        - "subnet-XXXX"
        - "subnet-YYYY"
      security_groups:
        - "sg-ZZZZ"
      assign_public_ip: ENABLED
```

調べてみると、同じエラーでハマっている先人を発見。
[Stopped Reason field not populated on "Failed to Start"](https://www.gitmemory.com/issue/aws/amazon-ecs-agent/1654/498406057)

awslogsドライバーで送り込んでいるログ設定が間違っていたとのこと。確かに怪しい。
試しに、CloudWatch Logsにログを送り込んでいる箇所を削ってみる。

```dockerfile:docker-compose.yml
version: '3'
services:
  web:
    image: amazon/amazon-ecs-sample
    ports:
      - "80:80"
```

あっさり**動いた。**

```zsh
% ecs-cli compose --project-name myFargateSvc service up
INFO[0000] Using ECS task definition                     TaskDefinition="myFargateSvc:3"
INFO[0000] Auto-enabling ECS Managed Tags
INFO[0010] (service myFargateSvc) has started 1 tasks: (task af78daabe9374bf6ae347c6526108201).  timestamp="2020-06-09 03:20:49 +0000 UTC"
INFO[0041] Service status                                desiredCount=1 runningCount=1 serviceName=myFargateSvc
INFO[0041] (service myFargateSvc) has reached a steady state.  timestamp="2020-06-09 03:21:19 +0000 UTC"
INFO[0041] ECS Service has reached a stable state        desiredCount=1 runningCount=1 serviceName=myFargateSvc
INFO[0041] Created an ECS service                        service=myFargateSvc taskDefinition="myFargateSvc:3"
```
<img width="1747" alt="スクリーンショット 2020-06-09 12.26.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/2ebc8acf-9fb3-267d-a15e-9a995b2c2f8b.png">
<img width="556" alt="スクリーンショット 2020-06-09 14.51.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/5c1d2af3-1f60-f1eb-7a78-4f5c0d065fa7.png">

スケーリングも自由自在。

```zsh
ecs-cli compose --project-name myFargateSvc service scale 3
INFO[0000] Updated ECS service successfully              desiredCount=3 force-deployment=false service=myFargateSvc
INFO[0000] Service status                                desiredCount=3 runningCount=1 serviceName=myFargateSvc
INFO[0010] (service myFargateSvc) has started 2 tasks: (task 7a6cef0567be470aa37f959a21764130) (task 8a75f3e18be443a28524fb357bed1375).  timestamp="2020-06-09 03:37:25 +0000 UTC"
INFO[0025] Service status                                desiredCount=3 runningCount=2 serviceName=myFargateSvc
INFO[0030] Service status                                desiredCount=3 runningCount=3 serviceName=myFargateSvc
INFO[0030] ECS Service has reached a stable state        desiredCount=3 runningCount=3 serviceName=myFargateSvc
```

いったいどういうことだ・・・？

最初に疑ったのは権限。
FargateからCloudWatchLogsにログを送り込むのに必要なのは、ecs-param.ymlにもあったこのロール、[ecsTaskExecutionRole](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_execution_IAM_role.html)のようだ。正確にはそこにアタッチされているAWS管理ポリシーAmazonECSTaskExecutionRolePolicy、もっと言うと`logs:XX`の権限とみられる。
ecsTaskExecutionRoleに絞ってググってみると、以下がヒットした。
[ecsTaskExecutionRoleを自作したらFargateにデプロイできなくなった注意点](https://keng000.hatenablog.com/entry/2019/08/30/065555)
[Unable to assume the service linked role when following the fargate tutorial #733](https://github.com/aws/amazon-ecs-cli/issues/733)

IAMをつぶさに調べてみる。
![スクリーンショット 2020-06-09 12.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/001b8ef0-d3e6-e9e0-1afc-e92b306d753d.png)

うーん、おかしくはなさそうだ。ポリシー上は、ログストリームを作成してログを送り込めない理由が見当たらない。

となるとネットワークか？
とさらにググって、参考になりそうなのを発見。
[Fargate: support launching tasks in offline subnets #48](https://github.com/aws/containers-roadmap/issues/48)

だが、よくよく考えてみると自分の設定はプライベートではなくパブリックサブネットなので、CloudWatch LogsへのPrivateLinkはいらないはず。念のため確認してみたがやはりインターネットへのコネクティビティがしっかり設定されているパブリックサブネットだった。これもボツ。

[公式](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cmd-ecs-cli-compose-ecsparams.html)を見ながら、ecs-params.ymlに足りてなさそうなパラメーターがないか探す。
手がかりなし。

そろそろ途方に暮れてきたので、投げやり気味な実力行使で打開を試みることにする。
先程のecsTaskExecitionRoleに立ち戻り、試しにCloudWatchLogsのフル権限（`CloudwatchLogsFullAccess`）を与えてみる。
<img width="401" alt="スクリーンショット 2020-06-09 13.23.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/c09f005e-f5c7-5826-ac3d-2c504d4b0bbc.png">

**何と動いた。**
ロググループ内のストリームも、今度は作成されている。
これはecsTaskExecutionRoleに割り当てられているAWS管理ポリシーが、Fargateを動かす上で実際には不足しているということか・・・？（似た経験あり）

と疑いつつも一応、もう一度フル権限を外して仮説検証してみると、**設定上は不動状態に戻ったはずなのにやっぱり動いてしまった。**
そしてこの後は、何度作り直しても何の問題もなく動作するようになったのだった・・・

### 結論

世の中には不思議なこともある。

（切り分け的には何の結論も出てませんが、トライアンドエラーの過程がどなたかの助けになるかも知れないので一応残しておきます）