[アップデート]AWS Batchで ECS Exec と AWS FireLensが使用できるようになりました
お疲れさまです。とーちです。
AWS Batchが ECS Exec と AWS FireLens ログルーターをサポートしたという嬉しいアップデートがありました。AWS Batchを利用している方は、このアップデートを待っていたという方も多いのではないでしょうか?
とりあえずまとめ
- AWS Batchが ECS Exec と AWS FireLens ログルーターをサポート
- ECS Exec によりバッチジョブ実行中のコンテナに接続してデバッグが可能になりました
- AWS FireLens ログルーターにより、ログを柔軟にルーティングできるようになりました
- ECS Exec及びAWS FireLens ログルーターの設定はジョブ定義にて指定します
- AWS Batchが利用できるすべてのAWSリージョンでサポートされています
やってみた
それでは早速、今回のアップデートを実際に試してみましょう。
下準備
今回のアップデートを試すためにAWS Batchのコンピューティング環境等を作成していきます。目新しい部分はないので、既にAWS Batchの作成方法は知っているという方は「アップデートで追加された部分の設定」まで読み飛ばして頂ければと思います。
前提として以下を予め作成しておきます
- VPC及びサブネット
- AWS Batchに紐づけるセキュリティグループ
- IAMロール
- タスク実行ロール(AWS管理ポリシーのAmazonECSTaskExecutionRolePolicyを付与)
- タスクロールについても事前に作成(作成方法は後述)
- ECR
- S3バケット
- ログ出力用
- fluentbit設定ファイル格納用
ECRには以下のコンテナイメージをbuildしてpushしておきます。"INFO ERROR EMERG"のいずれかのレベルのログをランダムに標準出力に出し90秒後に終了するだけのコンテナイメージです。
FROM alpine:latest
# ログ生成コマンドを実行し、90秒後に終了
CMD sh -c 'end_time=$(($(date +%s) + 90)); \
echo "ログ生成を開始します。90秒後に終了します。"; \
while [ $(date +%s) -lt $end_time ]; do \
# ランダムなログレベルとメッセージを生成 \
LEVEL=$(echo "INFO ERROR EMERG" | tr " " "\n" | shuf -n 1); \
echo "[$(date)] $LEVEL: Sample log message with status $(( $RANDOM % 600 ))"; \
sleep 1; \
done; \
echo "90秒経過しました。ログ生成を終了します。"'
まずはAWS Batchのコンピューティング環境を作ります。今回はFargateで作成しました。
ジョブキューは以下のような設定で作成しました。しばらくAWS Batchを触っていなかったのですが、いつからかジョブの状態制限という項目が追加されていたんですね。昔触ってた頃は設定ミスなどが原因でジョブが永遠に終わらない状態になっていたことがよくあったので良い設定だと思います。
アップデートで追加された部分の設定
ここからはアップデートで追加されたECS ExecとAWS FireLens ログルーターに関わる部分の設定をしていきます。
以下のIAMポリシーを持つIAMロールを作成しておきます。これはECS Execの実行及び、AWS FireLens ログルーターでログをS3にputするために必要な権限になります。
ECS Execの実行用ポリシー:
{
"Statement": [
{
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
}
AWS FireLens ログルーター用ポリシー:
{
"Statement": [
{
"Action": [
"s3:GetBucket*",
"s3:GetObject*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<fluentbit設定ファイル格納S3バケット名>",
"arn:aws:s3:::<fluentbit設定ファイル格納S3バケット名>/*"
]
},
{
"Action": [
"s3:PutObject*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<ログ出力用S3バケット名>",
"arn:aws:s3:::<ログ出力用S3バケット名>/*"
]
}
],
"Version": "2012-10-17"
}
また、FireLens ログルーター用コンテナイメージであるFluentbitでログをどこに出力するかを設定するためのファイルを fluentbit設定ファイル格納S3バケット
に配置しておきます。
fluentbit設定ファイルの内容は以下としました。すべてのログをS3バケットに出力する設定です。
[SERVICE]
Flush 1
Grace 30
[OUTPUT]
Name s3
Match *
region ap-northeast-1
bucket ${BUCKET_NAME}
total_file_size 1M
upload_timeout 1m
use_put_object On
compression gzip
s3_key_format /$TAG/%Y/%m/%d/%H/%M/%S/$UUID.gz
上記の準備ができたらAWS Batchのジョブ定義を作成していきましょう。
まず、ジョブ定義設定画面に入ったら以下の 「従来の containerProperties 構造を使用」のチェックを外しましょう。 これによりECS Exec等の設定が可能になります。
ジョブ定義全般の設定は以下のようにしました。赤枠で囲った箇所が今回のアップデートで追加されたECS Execを有効にするための設定になります。
アプリケーション側コンテナ(バッチ処理を実行したいコンテナ)の設定は以下の通りです。コンテナイメージには事前にECRにpushしておいたコンテナイメージを指定します。またログドライバーの設定で awsfirelens
を選択するようにしてください。
更にコンテナを追加ボタンを押してfirelens用のコンテナを設定していきます。
firelens用のコンテナの設定は以下としました。イメージにはPublicECRのAWS公式のFluentbitイメージを指定しています。タグに init-
がつくイメージを使うとS3(環境変数aws_fluent_bit_init_s3_1
でS3オブジェクトのARNを指定)からfluentbit設定ファイルを取得して動作します。また、fluentbit設定ファイル内で環境変数を使用して動的に出力先S3バケットを定義しているので、そのための環境変数(BUCKET_NAME)を指定しています。注意点として Firelensの設定
を忘れないようにしてください。これがないと設定を完了することができません。(私はここで少し詰まりました)
ジョブの実行とECS Execの検証
それではこの状態でジョブを実行してみましょう。ジョブの実行は作成したジョブ定義の画面のアクションから「新しいジョブを送信」で実行できます。
適当に名前をつけ、作成したジョブキューを指定してジョブを送信します。
しばらく待つと以下のようにジョブがRunnning状態になります。
この状態で、ECS Execを試してみます。マネージメントコンソールの(AWS Batchではなく)ECSの画面を開き、クラスターの一覧を見るとAWS Batchが作成したECSクラスター(AWSBatch-〜
)が存在しています。このECSクラスターをクリックし、タスクのタブから起動しようとしているタスクIDをコピーします。
コピーしたタスクIDやECSクラスター名を使って、ターミナルから aws ecs execute-command
コマンドを実行します。
> aws ecs execute-command --cluster AWSBatch-test-639a0839-4593-3996-a85c-6da3fe2a903c --task 923458ce79d34561a491b006bc1c8409 --container test-batch --interactive --command "/bin/sh"
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-q9t8sels2k8lb5gvoko3zpin5e
/ #
/ # ls
bin etc lib media opt root sbin sys usr
dev home managed-agents mnt proc run srv tmp var
/ # ps
PID USER TIME COMMAND
1 root 0:00 sh -c end_time=$(($(date +%s) + 90)); echo "ログ生成を開始します。90秒後に終了します。"; while [ $(date +%s) -lt $end_time ]; do LEVE
15 root 0:00 /managed-agents/execute-command/amazon-ssm-agent
37 root 0:00 /managed-agents/execute-command/ssm-agent-worker
214 root 0:00 /managed-agents/execute-command/ssm-session-worker ecs-execute-command-q9t8sels2k8lb5gvoko3zpin5e
225 root 0:00 /bin/sh
303 root 0:00 sleep 1
304 root 0:00 ps
/ #
psコマンドを実行するとたしかにバッチが実行されているコンテナであることが確認できました。これでECS Execが正常に動作していることが確認できました。
FireLensで出力したログの確認
Firelensで出力したログも見てみましょう。今回はS3バケットにログを出力しています。
以下のようにS3バケットにフォルダが作成されていました。今回はFluentbitの設定を s3_key_format /$TAG/%Y/%m/%d/%H/%M/%S/$UUID.gz
としているので、それに沿った階層でログが出力されています。ちなみにこの設定だと $TAG
の部分がECSタスクIDの値を含むため、以下のようにジョブごとにフォルダが作成されてしまいますね。
ログの中身はこのような形です。"log"の部分に実際コンテナで出力されたログが出ています。
{"date":"2025-04-15T22:55:50.843724Z","container_id":"d47f0a5a37a74ed392549c62b6aa01d7-XXXXXXXXXX","container_name":"test-batch","source":"stdout","log":"[Tue Apr 15 22:55:50 UTC 2025] INFO: Sample log message with status 300","ecs_cluster":"AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d47f0a5a37a74ed392549c62b6aa01d7","ecs_task_definition":"test:7"}
{"date":"2025-04-15T22:55:51.846273Z","source":"stdout","log":"[Tue Apr 15 22:55:51 UTC 2025] INFO: Sample log message with status 27","container_id":"d47f0a5a37a74ed392549c62b6aa01d7-XXXXXXXXXX","container_name":"test-batch","ecs_cluster":"AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d47f0a5a37a74ed392549c62b6aa01d7","ecs_task_definition":"test:7"}
{"date":"2025-04-15T22:55:52.848978Z","log":"[Tue Apr 15 22:55:52 UTC 2025] INFO: Sample log message with status 66","container_id":"d47f0a5a37a74ed392549c62b6aa01d7-XXXXXXXXXX","container_name":"test-batch","source":"stdout","ecs_cluster":"AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d47f0a5a37a74ed392549c62b6aa01d7","ecs_task_definition":"test:7"}
{"date":"2025-04-15T22:55:53.851661Z","container_id":"d47f0a5a37a74ed392549c62b6aa01d7-XXXXXXXXXX","container_name":"test-batch","source":"stdout","log":"[Tue Apr 15 22:55:53 UTC 2025] INFO: Sample log message with status 581","ecs_cluster":"AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d47f0a5a37a74ed392549c62b6aa01d7","ecs_task_definition":"test:7"}
{"date":"2025-04-15T22:55:54.854235Z","container_name":"test-batch","source":"stdout","log":"[Tue Apr 15 22:55:54 UTC 2025] ERROR: Sample log message with status 435","container_id":"d47f0a5a37a74ed392549c62b6aa01d7-XXXXXXXXXX","ecs_cluster":"AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/AWSBatch-test-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d47f0a5a37a74ed392549c62b6aa01d7","ecs_task_definition":"test:7"}
まとめ
以上、AWS Batch が Amazon Elastic Container Service Exec と AWS FireLens ログルーターをサポートしたというアップデートの紹介でした。
AWS BatchでもECS Execをサポートされたことでジョブ内で何か問題が起きているときに調査をしやすくなりましたね。またAWS FireLens ログルーターがサポートされたことでAWS Batchのログを柔軟にルーティングできるようになりました。ログを特定のSaaSに集約したいといったような要件にも対応できるようになったので、とても良いアップデートだと思います。
以上、とーちでした。