RDS をメンテしようと思い立つも、 ECS exec でポートフォワードできない。
❯ aws ssm start-session \ --target ecs:stg-tf-example-ecs-cluster_00001111222233334444555566667777_00001111222233334444555566667777-99998888 \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["example.example.ap-northeast-1.rds.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["13306"]}' \ --profile stg-example An error occurred (TargetNotConnected) when calling the StartSession operation: ecs:stg-tf-example-ecs-cluster_00001111222233334444555566667777_00001111222233334444555566667777-99998888 is not connected.
ファッキン! ということでデバッグ方法を調べた所、公式に以下のようなページが。
「AWS くんの公式ドキュメントめちゃくちゃ目が滑るんだよな」とずっと考えていたのだけど、日本語ドキュメントで <p>
的なアプローチをするのが良くないんだな、と最近思い始めている。
<br>
で改行するタイプの言語だよ。
それはさておき、結局権限が不足しているという話一点張りなので、どうやって調べろってのよまさか IAM 片っ端から見ろってのか! と思っていたら、本文中に以下へのリンクが出ている。
試す
ということで、 git clone
したのちに試した結果がこれ。
❯ export AWS_PROFILE=stg-example; ./check-ecs-exec.sh stg-tf-example-ecs-cluster 00001111222233334444555566667777 ------------------------------------------------------------- Prerequisites for check-ecs-exec.sh v0.7 ------------------------------------------------------------- jq | OK (/opt/homebrew/bin/jq) AWS CLI | OK (/opt/homebrew/bin/aws) ------------------------------------------------------------- Prerequisites for the AWS CLI to use ECS Exec ------------------------------------------------------------- AWS CLI Version | OK (aws-cli/2.9.9 Python/3.11.0 Darwin/22.2.0 source/arm64 prompt/off) Session Manager Plugin | OK (1.2.398.0) ------------------------------------------------------------- Checks on ECS task and other resources ------------------------------------------------------------- Region : ap-northeast-1 Cluster: stg-tf-example-ecs-cluster Task : 00001111222233334444555566667777 ------------------------------------------------------------- Cluster Configuration | Audit Logging Not Configured Can I ExecuteCommand? | arn:aws:iam::000011112222:user/donbulinux ecs:ExecuteCommand: allowed ssm:StartSession denied?: allowed Task Status | RUNNING Launch Type | Fargate Platform Version | 1.4.0 Exec Enabled for Task | OK Container-Level Checks | ---------- Managed Agent Status ---------- 1. RUNNING for "nginx" 2. RUNNING for "sidekiq" 3. RUNNING for "app" ---------- Init Process Enabled (stg-tf-example-ecs-task-definition-backend:4) ---------- 4. Disabled - "nginx" 5. Disabled - "app" 6. Disabled - "sidekiq" ---------- Read-Only Root Filesystem (stg-tf-example-ecs-task-definition-backend:4) ---------- 7. Disabled - "nginx" 8. Disabled - "app" 9. Disabled - "sidekiq" Task Role Permissions | arn:aws:iam::000011112222:role/ecs_task_execution_role ssmmessages:CreateControlChannel: disabled ssmmessages:CreateDataChannel: disabled ssmmessages:OpenControlChannel: disabled ssmmessages:OpenDataChannel: disabled VPC Endpoints | SKIPPED (vpc-09876543210987654 - No additional VPC endpoints required) Environment Variables | (stg-tf-example-ecs-task-definition-backend:4) 1. container "nginx" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: not defined - AWS_SECRET_ACCESS_KEY: not defined 2. container "app" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: defined - AWS_SECRET_ACCESS_KEY: defined 3. container "sidekiq" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: defined - AWS_SECRET_ACCESS_KEY: defined
ssmmessages
が無効化されとるやんけ! ということでマネジメントコンソールから IAM たどっていくと、たしかに ECS タスク定義にくっつけたロールの中身から欠落していた。
直接の原因は過去に書いた以下だった。
修正して再実行
というわけで、上記 ssmmessages
を再度付与して新しいタスク定義作成してローリングアップデート、 check-ecs-exec.sh
再実行した結果がこう。
❯ export AWS_PROFILE=stg-example; ./check-ecs-exec.sh stg-tf-example-ecs-cluster 00001111222233334444555566667777 ------------------------------------------------------------- Prerequisites for check-ecs-exec.sh v0.7 ------------------------------------------------------------- jq | OK (/opt/homebrew/bin/jq) AWS CLI | OK (/opt/homebrew/bin/aws) ------------------------------------------------------------- Prerequisites for the AWS CLI to use ECS Exec ------------------------------------------------------------- AWS CLI Version | OK (aws-cli/2.9.9 Python/3.11.0 Darwin/22.2.0 source/arm64 prompt/off) Session Manager Plugin | OK (1.2.398.0) ------------------------------------------------------------- Checks on ECS task and other resources ------------------------------------------------------------- Region : ap-northeast-1 Cluster: stg-tf-example-ecs-cluster Task : 00001111222233334444555566667777 ------------------------------------------------------------- Cluster Configuration | Audit Logging Not Configured Can I ExecuteCommand? | arn:aws:iam::000011112222:user/donbulinux ecs:ExecuteCommand: allowed ssm:StartSession denied?: allowed Task Status | RUNNING Launch Type | Fargate Platform Version | 1.4.0 Exec Enabled for Task | OK Container-Level Checks | ---------- Managed Agent Status ---------- 1. RUNNING for "nginx" 2. RUNNING for "sidekiq" 3. RUNNING for "app" ---------- Init Process Enabled (stg-tf-example-ecs-task-definition-backend:4) ---------- 4. Disabled - "nginx" 5. Disabled - "app" 6. Disabled - "sidekiq" ---------- Read-Only Root Filesystem (stg-tf-example-ecs-task-definition-backend:4) ---------- 7. Disabled - "nginx" 8. Disabled - "app" 9. Disabled - "sidekiq" Task Role Permissions | arn:aws:iam::000011112222:role/ecs_task_execution_role ssmmessages:CreateControlChannel: allowed ssmmessages:CreateDataChannel: allowed ssmmessages:OpenControlChannel: allowed ssmmessages:OpenDataChannel: allowed VPC Endpoints | SKIPPED (vpc-09876543210987654 - No additional VPC endpoints required) Environment Variables | (stg-tf-example-ecs-task-definition-backend:4) 1. container "nginx" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: not defined - AWS_SECRET_ACCESS_KEY: not defined 2. container "app" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: defined - AWS_SECRET_ACCESS_KEY: defined 3. container "sidekiq" - AWS_ACCESS_KEY: not defined - AWS_ACCESS_KEY_ID: defined - AWS_SECRET_ACCESS_KEY: defined
無事 allowed
になり、このあと ECS exec の利用もできるようになりましたとさ。
ということで、 ECS exec を利用できない時は公式が提供している、こちらのシェルスクリプトでチェックするようにしてみましょう。
default 以外のプロファイルを指定する
実行時に export
で環境変数からプロファイル名を与える以外は対応していないようです。 README にもそのようにやれと書いてあるので。
僕は複数行にするのが面倒なので、以下のようにワンライナーにしています。
export AWS_PROFILE=${プロファイル名}; ./check-ecs-exec.sh ${クラスタ名} ${タスクID}
disabled 全部潰したのに接続できない時
僕は本番向け prod-
と検証向け stg-
という prefix を利用しているのですが、接続文言をコピペで使いまわしており、以下のようなミスが原因でした。
# 検証に接続したい ❯ aws ssm start-session \ --target ecs:stg-tf-example-ecs-cluster_00001111222233334444555566667777_00001111222233334444555566667777-99998888 \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["example.example.ap-northeast-1.rds.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["13306"]}' \ --profile stg-example # 本番に接続した ❯ aws ssm start-session \ --target ecs:stg-tf-example-ecs-cluster_00001111222233334444555566667777_00001111222233334444555566667777-99998888 \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["example.example.ap-northeast-1.rds.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["13306"]}' \ --profile prod-example
実際にミスったヤツです、目が滑りますね。 原因は ECS クラスタ名の指定の変更が間違っています。
検証は合っているけど、本番もコピペしたのち --profile
の指定をかえただけで接続できずキレていました。 このあたり AWS 側の例外メッセージも不親切だったりするのですが、一番良いのはコマンドで済ませるより対話型 CLI などで選択する、という方がよさそうです。
探したら作っている人はいるのだった。
こちらもあるじゃん!と思っていたら EC2 対象でした……。