AWS ECS Exec と Exec Checker を使ってみた

# Exec Checker で Exec 環境をチェックする

`jq` コマンドをインストールしておきます。実行方法は、以下の通りです。

```
sh check-ecs-exec.sh <container name> <task id>
```

リポジトリは以下になります。

https://github.com/aws-containers/amazon-ecs-exec-checker

こちらのチェッカーはユーザーガイドに記載されています。

> **Amazon ECS Exec Checker を使用した確認**
>
> Amazon ECS Exec Checker スクリプトにより、Amazon ECS クラスターとタスクが ECS Exec 機能を使用するための前提条件を満たしていることを確認および検証できます。このツールを使用するには、AWS CLI の最新バージョンが必要であり、jq が使用可能であることが必要です。詳細については、GitHub の Amazon ECS Exec Checker を参照してください。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-exec.html


- AWS CLI のバージョンが古い場合

`ECS Exec requires the AWS CLI v1.19.28/v2.1.30 or later.` と表示されています。

```
$ sh check-ecs-exec.sh exec-demo 9ef2e3c658e84a65a5c71c1d06b0a892
-------------------------------------------------------------
Prerequisites for check-ecs-exec.sh v0.6
-------------------------------------------------------------
  jq      | OK (/usr/bin/jq)
  AWS CLI | OK (/usr/bin/aws)

-------------------------------------------------------------
Prerequisites for the AWS CLI to use ECS Exec
-------------------------------------------------------------
Pre-flight check failed: ECS Exec requires the AWS CLI v1.19.28/v2.1.30 or later.
Please update the AWS CLI and try again?
  For v2: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html
  For v1: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html
```

- Session Manager Plugin がインストールされていない場合

`Session Manager Plugin | Missing` と表示されています。

```
$ sh check-ecs-exec.sh exec-demo 9ef2e3c658e84a65a5c71c1d06b0a892
-------------------------------------------------------------
Prerequisites for check-ecs-exec.sh v0.6
-------------------------------------------------------------
  jq      | OK (/usr/bin/jq)
  AWS CLI | OK (/usr/bin/aws)

-------------------------------------------------------------
Prerequisites for the AWS CLI to use ECS Exec
-------------------------------------------------------------
  AWS CLI Version        | OK (aws-cli/2.2.25 Python/3.8.8 Linux/4.14.238-182.422.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off)
  Session Manager Plugin | Missing
```

- `"enableExecuteCommand": false` の場合

`Exec Enabled for Task  | NO` と表示されています。CLI 実行時に `--enable-execute-command` が必要です。

```
sh check-ecs-exec.sh exec-demo addfe8f3365c4782879da1bc34864799
-------------------------------------------------------------
Prerequisites for check-ecs-exec.sh v0.6
-------------------------------------------------------------
  jq      | OK (/usr/bin/jq)
  AWS CLI | OK (/usr/bin/aws)

-------------------------------------------------------------
Prerequisites for the AWS CLI to use ECS Exec
-------------------------------------------------------------
  AWS CLI Version        | OK (aws-cli/2.2.25 Python/3.8.8 Linux/4.14.238-182.422.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off)
  Session Manager Plugin | OK (1.2.234.0)

-------------------------------------------------------------
Checks on ECS task and other resources
-------------------------------------------------------------
Region : ap-northeast-1
Cluster: exec-demo
Task   : addfe8f3365c4782879da1bc34864799
-------------------------------------------------------------
  Cluster Configuration  | Audit Logging Not Configured
  Can I ExecuteCommand?  | arn:aws:iam::123456789012:role/EC2Role
     ecs:ExecuteCommand: allowed
     ssm:StartSession denied?: implicitDeny
  Task Status            | RUNNING
  Launch Type            | Fargate
  Platform Version       | 1.4.0
  Exec Enabled for Task  | NO
```

以下は出力の一部を取り出したものですが、Exec に必要な権限がタスクロールに割り当てられているかどうかを検証し、その結果を出力しています。

```
  Task Role Permissions  | arn:aws:iam::123456789012:role/ExecRole
     ssmmessages:CreateControlChannel: allowed
     ssmmessages:CreateDataChannel: allowed
     ssmmessages:OpenControlChannel: allowed
     ssmmessages:OpenDataChannel: implicitDeny
```

このチェッカーを使用するために必要な `iam:SimulatePrincipalPolicy` という権限がないメッセージが表示されています。

```
$ sh check-ecs-exec.sh exec-demo 9ef2e3c658e84a65a5c71c1d06b0a892
-------------------------------------------------------------
Prerequisites for check-ecs-exec.sh v0.6
-------------------------------------------------------------
  jq      | OK (/usr/bin/jq)
  AWS CLI | OK (/usr/bin/aws)

-------------------------------------------------------------
Prerequisites for the AWS CLI to use ECS Exec
-------------------------------------------------------------
  AWS CLI Version        | OK (aws-cli/2.2.25 Python/3.8.8 Linux/4.14.238-182.422.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off)
  Session Manager Plugin | Missing

-------------------------------------------------------------
Checks on ECS task and other resources
-------------------------------------------------------------
Region : ap-northeast-1
Cluster: exec-demo
Task   : 9ef2e3c658e84a65a5c71c1d06b0a892
-------------------------------------------------------------
  Cluster Configuration  | Audit Logging Not Configured
  Can I ExecuteCommand?  | arn:aws:iam::123456789012:role/EC2Role

An error occurred (AccessDenied) when calling the SimulatePrincipalPolicy operation: User: arn:aws:sts::123456789012:assumed-role/EC2Role/i-0427baf184543ab0e is not authorized to perform: iam:SimulatePrincipalPolicy on resource: arn:aws:iam::123456789012:role/EC2Role
```

スクリプトにも記載されていますが、checker に必要な権限は以下の通りです。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetInstanceProfile",
                "iam:SimulatePrincipalPolicy",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcEndpoints",
                "ecs:DescribeClusters",
                "ecs:DescribeContainerInstances",
                "ecs:DescribeTaskDefinition",
                "ecs:DescribeTasks"
            ],
            "Resource": "*"
        }
    ]
}
```

# Exec の使用

必要なことは次の 4 点です。

- AWS CLI v1.19.28/v2.1.30 のインストール
- Session Manager Plugin のインストール
- タスクロールに Exec に必要な権限を設定する
- タスク実行時に `--enable-execute-command` を渡す

AWS CLI の v2 の最新版をインストールします。

```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install -i /usr/local/aws-cli -b /usr/bin
aws --version
```

`aws-cli/2.2.25` が `v2.1.30` 以降のバージョンであるメッセージを確認します。

```
aws-cli/2.2.25 Python/3.8.8 Linux/4.14.238-182.422.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off
```

Session Manager Plugin をインストールします。

```
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm"
sudo yum install -y session-manager-plugin.rpm
session-manager-plugin
```

以下のメッセージを確認します。

```
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
```

タスクロールに以下のポリシーをアタッチします。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}
```

`--enable-execute-command` をオプションで指定してタスクを実行します。

```
aws ecs run-task \
  --launch-type FARGATE \
  --cluster exec-demo \
  --task-definition exec-demo \
  --network-configuration awsvpcConfiguration="{subnets=[subnet-xxxxxx],securityGroups=[sg-yyyyyy],assignPublicIp=ENABLED}" \
  --enable-execute-command
```

上記のコマンドを実行すると、JSON フォーマットが出力されますので、`taskArn` というキーを見つけます。`c61f0147d08749b3842888fa40980807` が ID です。

```
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/exec-demo/c61f0147d08749b3842888fa40980807"
```

以下を実行します。

```
aws ecs execute-command \
  --cluster exec-demo \
  --task c61f0147d08749b3842888fa40980807 \
  --container exec-demo \
  --interactive \
  --command "/bin/bash"
```

成功すると以下のメッセージが表示され、コンテナに入ることができます。

```
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-0f50e6127b6507aea
```

コンテナ内部でアプリケーションにアクセスしてみます。

```
root@ip-172-31-19-245:/usr/src/app# curl -i localhost:8080
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 11
ETag: W/"b-Ck1VqNd45QIvq3AZd8XYQLvEhtA"
Date: Sun, 01 Aug 2021 01:40:41 GMT
Connection: keep-alive
Keep-Alive: timeout=5

Hello World
```

# 参考記事

https://aws.amazon.com/jp/blogs/news/new-using-amazon-ecs-exec-access-your-containers-fargate-ec2/

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-exec.html

https://github.com/aws-containers/amazon-ecs-exec-checker

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#install-plugin-linux

https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html

https://qiita.com/okubot55/items/b1fb07b2de08c354275b