はじめに
Amazon ECS (Elastic Container Service) でタスク内のコマンドを実行する際、ECS Exec は非常に便利です。しかし、コマンドの実行やロールの権限変更といった作業を都度行うのは手間がかかります。
この問題を解消するために、自動化スクリプトを作成しました。本記事では、ECS Exec を利用するための基本手順と、その手順を自動化するスクリプトについてご紹介します。
前提
この記事では以下の内容については説明していませんので、事前に設定されていることを前提としています。これらの設定がまだの場合は、AWSの公式ドキュメントや別の記事を参考にしてください。
スクリプトを実行するためのIAMロールやユーザーの作成
スクリプトを実行するには、AWS CLIを使用できる権限が必要です。
権限を持つロールまたはユーザーを事前に作成してください。
AWS CLIの--profileオプションの設定
スクリプトでは--profileオプションを使用しています。
プロファイルは、AWS CLIのaws configureコマンドで事前に設定してください。
ECS Exec を利用する手順
ECS Execを利用するには、以下の手順を踏む必要があります。
今回は以下の手順をスクリプト化しました。
ECS Execを有効化
ECSサービスでexecコマンドを使うには、aws ecs update-service
を使って--enable-execute-command
を有効にする必要があります。
また、有効にした後はタスクを立ち上げ直す必要があります。
適切なIAMポリシーを付与
ECS Execを使うには、ECSタスクがSSM経由で接続されるため以下の権限が必要です。
本記事ではサンプルとして広めの権限を付与しておりますが、適宜変更してください。
ecs:ExecuteCommand
ssmmessages:CreateDataChannel
ssmmessages:OpenDataChannel
ssmmessages:CreateControlChannel
ssmmessages:OpenControlChannel
IaC の活用について
本記事では、スクリプトを利用してECS Execの有効化を手動で設定する方法を解説していますが、より効率的な運用を目指す場合、IaC (Infrastructure as Code) を用いて ECS Exec を有効化した状態でリソースを構築することも可能です。Terraform や AWS CDK を使用して、ECS サービスに必要な設定をあらかじめ含めておくと、作業の簡略化が可能です。
手順をスクリプトで自動化する
この記事で紹介するスクリプトは、ECS クラスターおよびサービスが既に存在していることを前提としています。また、既に稼働中のタスクがある場合は、スクリプト実行後にタスクを再起動する必要があります。なお、タスクの再起動については、誤って本番環境でスクリプトを実行した際のリスクを考慮し、スクリプトに含めていません。
policyの権限は要件に合わせて適宜変更してください
#!/bin/bash
# Variables
PROFILE="" # 使用するAWS CLIプロファイル名
POLICY_NAME="ECSExecuteCommandPolicy"
ROLE_NAME="" # ECSロール名(タスク実行ロールではない)
CLUSTER_NAME="" # クラスターの名前
SERVICE_NAME="" # サービスの名前
# Replace placeholders
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text --profile $PROFILE)
# JSON Policy Content
POLICY_DOCUMENT=$(cat <<EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ecs:ExecuteCommand",
"Resource": [
"arn:aws:ecs:*:${ACCOUNT_ID}:task/*/*",
"arn:aws:ecs:ap-northeast-1:${ACCOUNT_ID}:cluster/${CLUSTER_NAME}"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:CreateControlChannel"
],
"Resource": "*"
}
]
}
EOT
)
# Create Policy
echo "Creating policy $POLICY_NAME..."
POLICY_ARN=$(aws iam create-policy \
--profile $PROFILE \
--policy-name $POLICY_NAME \
--policy-document "$POLICY_DOCUMENT" \
--query 'Policy.Arn' \
--output text)
if [ $? -eq 0 ]; then
echo "Policy created: $POLICY_ARN"
else
echo "Failed to create policy."
exit 1
fi
# Attach Policy to Role
echo "Attaching policy to role $ROLE_NAME..."
aws iam attach-role-policy \
--profile $PROFILE \
--role-name $ROLE_NAME \
--policy-arn $POLICY_ARN
if [ $? -eq 0 ]; then
echo "Policy attached successfully to $ROLE_NAME."
else
echo "Failed to attach policy to $ROLE_NAME."
exit 1
fi
# Enable ECS Execute Command
echo "Enabling execute command for service $SERVICE_NAME in cluster $CLUSTER_NAME..."
aws ecs update-service \
--profile $PROFILE \
--cluster $CLUSTER_NAME \
--service $SERVICE_NAME \
--enable-execute-command
if [ $? -eq 0 ]; then
echo "Execute command enabled successfully for service $SERVICE_NAME in cluster $CLUSTER_NAME."
else
echo "Failed to enable execute command for service $SERVICE_NAME in cluster $CLUSTER_NAME."
exit 1
fi
echo "All tasks completed successfully."
ECS Execコマンドの実行
タスクARNを動的に取得してECS Execを実行します。
#!/bin/bash
CLUSTER_NAME=""
SERVICE_NAME=""
CONTAINER_NAME=""
PROFILE_NAME=
TASK_ARN=$(aws ecs list-tasks \
--cluster "$CLUSTER_NAME" \
--service-name "$SERVICE_NAME" \
--desired-status RUNNING \
--query "taskArns[0]" \
--output text \
--profile "$PROFILE_NAME")
aws ecs execute-command \
--cluster "$CLUSTER_NAME" \
--task "$TASK_ARN" \
--container "$CONTAINER_NAME" \
--interactive \
--command "/bin/sh" \
--profile "$PROFILE_NAME"
最後に
ECS Exec を利用する際、コマンド実行までの手間を軽減するため、スクリプトを作成しました。手動で作業する場合に比べ、時間を短縮できるかと思います。本スクリプトを活用して、より効率的な運用を目指してください。