個人的備忘録：ECS Exec の概要とコマンド、ベストプラクティスを体系的にまとめてみた

## はじめに
まず、大前提として、ここから先は ECS Exec について体系的に整理し、自分の知識を深めることを目的としています。

:::note alert
**※補足事項**
***そのため、内容は完全に自分向けとなっています。***
:::

また、このブログ投稿サイトのプラットフォームについても、自分自身の備忘録としてメモを残す場として活用していきたいと考えています。***このプラットフォーム上に記録を積み重ねていく予定です。***

もし誤りがあれば、コメントなどで教えていただけると幸いです。

## ECS Exec とは？
ECS Exec は、AWS Elastic Container Service (ECS) 上で稼働しているコンテナに対して、シェルアクセスやリモートデバッグを可能にする機能です。

![Screenshot 2025-02-21 at 5.38.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/193a256a-3232-4707-9ca6-b3c75fc666df.png)
引用画像：https://qiita.com/okubot55/items/b1fb07b2de08c354275b

SSH や Bastion サーバーなしに、AWS Systems Manager (SSM) を活用してコンテナに直接アクセスできます。

この機能を使用すると、以下のような利点があります。
- **セキュリティの向上**: SSHキーの管理が不要。
- **運用の簡素化**: Bastion ホストなしでコンテナにアクセス可能。
- **監査ログの取得**: AWS CloudTrail で実行履歴を追跡。

## ECS Exec の前提条件
ECS Exec を使用するには、以下の前提条件を満たす必要があります。

1. **ECS クラスターとタスクが AWS Fargate または EC2 上で稼働している**
2. **タスク IAM ロールに必要なポリシーが付与されている**
3. **AWS CLI のバージョンが v1.19.28 以降（推奨 v2）**
4. **ECS エージェントが v1.50.2 以降（EC2 を使用する場合）**
5. **AWS Systems Manager (SSM) Agent が有効**
6. **タスク定義に `enableExecuteCommand` を設定**

### IAM ロールの設定
タスク実行ロールに以下のポリシーを追加します。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:StartSession",
        "ssm:DescribeSessions",
        "ssm:TerminateSession",
        "ecs:ExecuteCommand"
      ],
      "Resource": "*"
    }
  ]
}
```

## ECS Exec の有効化
ECS Exec を使用するには、タスク定義またはサービスで `enableExecuteCommand` を有効にする必要があります。

### 1. タスク定義で有効化
タスク定義の `executionRoleArn` に IAM ロールを設定し、以下のパラメータを追加します。

```json
{
  "containerDefinitions": [
    {
      "name": "my-container",
      "image": "my-image",
      "essential": true,
      "command": ["sh", "-c", "while true; do sleep 30; done"],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-task",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ],
  "enableExecuteCommand": true
}
```

### 2. 既存のサービスで有効化
AWS CLI を使用して既存のサービスに `--enable-execute-command` を適用します。

```sh
aws ecs update-service --cluster my-cluster --service my-service --enable-execute-command
```

## ECS Exec の使い方
### 1. タスク ID の取得
まず、ターゲットのコンテナが動作しているタスクの ID を取得します。

```sh
aws ecs list-tasks --cluster my-cluster
```

上記のコマンドで出力される `taskArn` からタスク ID を確認します。

### 2. コンテナ名の取得
特定のタスクのコンテナ名を取得するには、次のコマンドを実行します。

```sh
aws ecs describe-tasks --cluster my-cluster --tasks my-task-id
```

### 3. 実行コマンド
コンテナにアクセスするには、以下のコマンドを使用します。

```sh
aws ecs execute-command --cluster <ECSクラスタ名> \
  --task <新しいタスクID> \
  --container my-app-repo \
  --command "/bin/sh" \
  --interactive
```

このコマンドを実行すると、コンテナ内で `/bin/sh` セッションが開き、コンテナ内の環境を直接操作できます。

### 4. 既存のセッションの確認
現在アクティブなセッションを確認するには、以下のコマンドを実行します。

```sh
aws ssm describe-sessions --state Active
```

### 5. セッションの終了
セッションを終了するには、通常の `exit` コマンドを入力するか、次のコマンドを実行します。

```sh
aws ssm terminate-session --session-id my-session-id
```

## トラブルシューティング
### 1. `execute-command` が動作しない
- **`enableExecuteCommand` が設定されているか確認**
- **タスクの IAM ロールに `ecs:ExecuteCommand` の権限があるか確認**
- **ECS エージェントと SSM エージェントが最新バージョンであるか確認**

### 2. `aws ssm` コマンドでエラーが出る
- **IAM ユーザーに SSM の権限 (`ssm:StartSession`) が付与されているか確認**
- **CloudWatch Logs にエラーが記録されていないか確認**

## まとめ
ECS Exec を使用すると、SSH や Bastion サーバーを使わずに、セキュアにコンテナへアクセスできます。AWS CLI を活用して簡単にコンテナ内部での操作ができるため、デバッグやトラブルシューティングの効率が向上します。

ECS Exec を活用し、安全で便利な運用を実現していきたいです。