ecspresso execコマンド

ecspressoのexecコマンドを使うとECS exec を利用したコンテナへの接続を実現できる。

準備

TerraformとecspressoでECS(Fargete)を構築する で作成したTerraformとecspressoのコードを用意する。

ECS execの有効化

ECS execを有効にするためにはサービス定義に以下の設定を追加する。

-  "enableExecuteCommand": false,
+  "enableExecuteCommand": true,

ECS execでアクセスするための権限

IAM Roleの作成

ECS execでコンテナに接続するためにはssmmessages:*権限を持ったIAM Roleをタスクに割り当てる必要がある。

まずIAM Roleを作成する。

data "aws_iam_policy_document" "task_assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "task_role" {
  name               = "task_role"
  assume_role_policy = data.aws_iam_policy_document.task_assume_role.json
  inline_policy {
    name = "ssmpolicy"
    policy = jsonencode(
      {
        Version = "2012-10-17"
        Statement = [
          {
            Effect = "Allow"
            Action = [
              "ssmmessages:CreateControlChannel",
              "ssmmessages:CreateDataChannel",
              "ssmmessages:OpenControlChannel",
              "ssmmessages:OpenDataChannel"
            ]
            Resource = "*"
          }
        ]
      }
    )
  }
}

AWS CLIなどで他のリソースへのアクセスが必要な場合はさらに権限を追加する。

タスクロールにアタッチ

上記で作成したIAM Roleをサービス定義のtaskRoleARNへ設定する。

+  "taskRoleARN": "{{ tfstate `aws_iam_role.task_role.arn` }}",

適用

Terraformで変更を適用する。

$ terraform apply

次にecspressoでサービスを更新する。

$ ecspresso deploy --config ecspresso/ecspresso.yml

ecspresso execで接続

ecspressoのexecコマンドでコンテナに接続する。

$ ecspresso exec --config ecspresso/ecspresso.yml
2024/06/15 05:43:59 [INFO] ecspresso version: v2.3.4

Starting session with SessionId: ecs-execute-command-mzvzsradtdqybo3jipl76o2jra
# ls
bin  boot  dev	docker-entrypoint.d  docker-entrypoint.sh  etc	home  lib  lib64  managed-agents  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

今回の例ではタスクが1つであるため即座に接続される。
複数のタスクがある場合はタスクを選択するためのプロンプトが表示される。

サービス定義でdesiredCountを変更して複数のタスクを起動してからexecコマンドを実行すると以下のようになる。

$ ecspresso exec --config ecspresso/ecspresso.yml
014e2c21fbe244bda26c54778bc490f2	terraform-ecspresso-sample:17		RUNNING	RUNNING	2024-06-15T05:55:12+09:00	service:nginx	FARGATE
ab25612c96ea453fa16cc03ced795a1f	terraform-ecspresso-sample:17		RUNNING	RUNNING	2024-06-15T05:55:12+09:00	service:nginx	FARGATE
Enter task ID:

1列目のタスクIDを指定するとそのコンテナに接続される。

task ID=ab25612c96ea453fa16cc03ced795a1f

Starting session with SessionId: ecs-execute-command-g5kn7wcvgsxq6ftmpcw7odrxmy
#

単発のコマンドを実行したい場合は--commandオプションを指定する。

$ ecspresso exec --config ecspresso/ecspresso.yml --command "cat /etc/os-release"
2024/06/15 05:45:27 [INFO] ecspresso version: v2.3.4

Starting session with SessionId: ecs-execute-command-sk3p3ctgc2erbyfxs66obso2ra
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"


Exiting session with sessionId: ecs-execute-command-sk3p3ctgc2erbyfxs66obso2ra.

ポートフォワード

ECS execでポートフォワードするには--port-forwardオプションを指定する。

例えばRDSを使用していて5432ポートをローカルの15432ポートに転送するには以下のようにする。

$ ecspresso exec --config ecspresso/ecspresso.yml \
  --port-forward 5432 --local-port 15432 --host <RDSのエンドポイント>

上記コマンドによってポートフォワードが成功すると、ローカルの15432ポートへのアクセスでRDSにアクセスできる。

-Lオプションを指定すると1つのオプションで複数のポートを転送できる。

$ ecspresso exec --config ecspresso/ecspresso.yml \
  -L 5432:<RDSのエンドポイント>:15432