ECS Fargateのコンテナ内にECS Execでアクセスする方法 (踏み台EC2あり)


# はじめに
ECS Execの機能を使って、Fargateのコンテナにアクセスする方法を記載します。

ECS Execによるコンテナへのアクセスは、以下の4つを行うことで実行できます。

- クライアントサーバーには、ECS Exec コマンドを実行するための AWS CLI がインストールされていること

- クライアントサーバーには、AWS CLI 用の `Session Manager plugin` がインストール

- `enable-execute-command`を使い、Fargateのタスク定義の`enableExecuteCommand `を有効にすることで、ECS Exec の機能が有効になります。

- コンテナがSystems Managerと連携するため、FargateのタスクロールにIAM権限を付与します。
下記に記事に、詳細な理由が記載されています。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html
>ECS Exec 機能には、マネージド型 SSM エージェント (execute-command エージェント) と SSM サービス間の通信に必要なアクセス許可をコンテナに付与するためのタスク IAM ロールが必要です。

# 構築図
今回は、EC2を踏み台サーバーとして使い、Systems Manager の Session Manager 経由で、`execute-command`を用いて、コンテナにアクセスします。
EC2には、Systems Manager の Session Managerを使用するため、`Session Manager plugin` のインストールが必要です。


![スクリーンショット 2021-10-25 23.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5e04ad87-3571-40d0-1f2b-49f0c33ac801.png)

:::note warn
踏み台サーバーではなく、ローカルPCから直接コンテナにアクセスする場合、こちらの記事を参考にしてください

https://qiita.com/holdout0521/items/261d06c3fb0c39b014e0
:::


# 流れ
1. IAMポリシーとロール作成
1. EC2にSession Manager pluginをインストール
1. ECSのタスクロールにIAM権限を付与
1. ECSのサービスにECS Execの機能を有効にする
1. Fargateのコンテナにアクセス


# 前提条件
- ECS作成済み
WordPressFargateの作成方法はこちら
[Fargate＋WordPress構築](https://qiita.com/holdout0521/items/bde67b8334f3362c8009)

- Fargate プラットフォームバージョン 1.4.0

- コマンドは全て、踏み台サーバーで実行します。

# IAMポリシーとロール作成
以下のようにロールを作成します。

|IAMロール名	  |ポリシー	| 付与先サービス| 目的|
| ---- | ---- | ---- | ---- |
| ECS-Exec-Fargate-role | ECS-Exec-Fargate |ECS | コンテナにアクセスするためには execute-command を用いて、SSM サービス間の通信が必要なため |  
| ECS-Exec-EC2-role |Amazon ECS_FullAccess  | EC2 | ECS execを利用しECSにアクセスするため | 

 

`ECS-Exec-Fargate`という名前のIAMポリシーを作成します。

```json:ECS-Exec-Fargate
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "ssmmessages:CreateDataChannel",
        "ssmmessages:OpenDataChannel",
        "ssmmessages:OpenControlChannel",
        "ssmmessages:CreateControlChannel"
      ],
      "Resource": "*"
    }
  ]
}
```
`ECS-Exec-Fargate-role`のロールを作成します。
- `ユースケースの選択`：`ECS`の`Elastic Container Service Task`
先程作成した`ECS-Exec-Fargate`ポリシーをアタッチします。


![スクリーンショット 2021-10-23 23.41.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/ca06d2e6-fff9-a4fc-d07b-02b63e223784.png)

![スクリーンショット 2021-10-24 11.55.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5b345af0-37ae-5ac8-f77f-d1e70327891b.png)


次に、`Amazon ECS_FullAccess`管理ポリシーを付与した`ECS-Exec-EC2-role`を作成し、EC2にIAMロールを付与します。


![スクリーンショット 2021-10-23 23.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5ac0c765-e5c8-aed6-e63f-dc0252e6bbe6.png)

![スクリーンショット 2021-10-24 11.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/b4591407-2bbe-886f-3d7e-64c005b4c823.png)

# EC2に` Session Manager plugin `をインストール

ECS Exec コマンドを実行するための AWS CLI がインストールされていること必須なため、CLIが以下の条件に当てはまるか確認します。

```
AWS CLI v1 バージョン 1.19.28以上
             or
AWS CLI v2 バージョン 2.1.31以上
```
踏み台サーバーのEC2にSSH接続し、以下のコマンドで確認します。

```terminal
$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.246-187.474.amzn2.x86_64 botocore/1.18.6
```
バージョンが当てはまらないので、CLIの最新版をインストールしましょう。


```terminal
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

$ unzip awscliv2.zip

$ sudo ./aws/install

$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.246-187.474.amzn2.x86_64 botocore/1.18.6
```

バージョンが変わっていないため、再起動後SSH接続し、バージョンを確認します

```terminal
$ sudo reboot

$ aws --version
aws-cli/2.3.0 Python/3.8.8 Linux/4.14.248-189.473.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off
```
バージョンが最新になりました。

Session Manager プラグインをインストールしましょう！

```terminal
$ 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.
```
インストールできました。

# ECSのタスクロールにIAM権限を付与
コンテナがSystems Managerと連携するため、FargateのタスクロールにIAM権限を付与します。

タスク定義のタスクロールに`ECS-Exec-Fargate-role`を選択し、サービスを更新します。
![スクリーンショット 2021-10-24 11.56.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5a37024b-7157-5d84-16f8-8ccfa8bb9a3e.png)


サービスを最新バージョンに更新して、タスクを立ち上げましょう。

## タスクロールとタスク実行ロールの違いについて
`タスク実行ロール`は、ECSコンテナエージェントがECRからのコンテナイメージプルや、コンテナログをCloudWatchに送信するためIAMポリシーが必要となります。

対して、`タスクロール`は、コンテナが他のAWSサービスと連携する際にのみ、必要なIAMポリシーを設定します。

今回であれば、コンテナが`Systems Manager`と連携するため、`タスクロール`に権限を付与したということになります。
![スクリーンショット 2021-10-24 12.14.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/d63f7b23-8cd7-97fa-0deb-a466aa557684.png)

# ECSのサービスにECS Execの機能を有効にする

`enable-execute-command`を用いて、`enableExecuteCommand`を有効にすることで、ECS Exec の機能を有効にすることができます。
タスクが立ち上がっていることを確認し、以下のコマンドを実施しましょう。

成功すると、長文の結果が返ってきますので、エンターを押し続けてください。

```terminal
$ aws ecs update-service \
    --cluster クラスター名 \
    --service サービス名 \
    --enable-execute-command

#省略(結果は長いです。エンターを押し続けましょう)
     "enableExecuteCommand": true
  }
}
```


もしくは以下のコマンドでも、Exec の機能が有効どうか確認できます。
`true`と返ってきたら、有効ということです。

```terminal
$ aws ecs describe-services --cluster クラスター名 --services サービス名 | jp.py 'services[].enableExecuteCommand'

[
    true
]
```

## エラー集
以下のようなエラーが出た場合、サービスの実行ロールに`ECS-Exec-Fargate-role`を付与し、そのサービスを更新していない可能性があります。
または、FargateのIAMポリシーが不適切、もしくはEC2に`ECS-Exec-EC2-role`を付与していないことも考えられます。

```terminal
$ aws ecs update-service \
    --cluster クラスター名 \
    --service サービス名\
    --enable-execute-command

An error occurred (InvalidParameterException) when calling the UpdateService operation: The service couldn't be updated because a valid taskRoleArn is not being used. Specify a valid task role in your task definition and try again.
```


# Fargateのコンテナにアクセス
まず、起動しているタスクを全て停止し、再度タスクを起動します。
そして、`execute-command`を使い、コンテナにアクセスします。
`タスクID`は、稼働中（Running）のものに限ります。

```terminal
$ aws ecs execute-command \
    --cluster クラスター名 \
    --task タスクID \
    --container コンテナ名 \
    --interactive \
    --command "/bin/sh"



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

Starting session with SessionId: 
```

コンテナにアクセスできました！！

## エラー集

ECS Execの機能を有効にしていない場合に、`execute-command`を使用すると以下のエラーが起きます。
有効にし、サービスを更新し、タスクを再起動しましょう。

```terminal
$ aws ecs execute-command \
    --cluster クラスター名 \
    --task タスクID \
    --container コンテナ名 \
    --interactive \
    --command "/bin/sh"

An error occurred (InvalidParameterException) when calling the ExecuteCommand operation: The execute command failed because execute command was not enabled when the task was run or the execute command agent isn’t running. Wait and try again or run a new task with execute command enabled and try again.
```

# 参考

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

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

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

https://dev.classmethod.jp/articles/ecs-exec-enableexecutecommand-error/