[アップデート]AWS Batchで ECS Exec と AWS FireLensが使用できるようになりました

[アップデート]AWS Batchで ECS Exec と AWS FireLensが使用できるようになりました

AWS Batchで ECS Exec と AWS FireLensが使用できるようになりました!
Clock Icon2025.04.16

お疲れさまです。とーちです。

AWS Batchが ECS Exec と AWS FireLens ログルーターをサポートしたという嬉しいアップデートがありました。AWS Batchを利用している方は、このアップデートを待っていたという方も多いのではないでしょうか?

https://aws.amazon.com/about-aws/whats-new/2025/04/aws-batch-amazon-elastic-container-service-exec-firelens-log-router

とりあえずまとめ

  • 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のコンピューティング環境設定画面

ジョブキューは以下のような設定で作成しました。しばらくAWS Batchを触っていなかったのですが、いつからかジョブの状態制限という項目が追加されていたんですね。昔触ってた頃は設定ミスなどが原因でジョブが永遠に終わらない状態になっていたことがよくあったので良い設定だと思います。

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等の設定が可能になります。

従来の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の設定 を忘れないようにしてください。これがないと設定を完了することができません。(私はここで少し詰まりました)

firelens用コンテナの設定画面

ジョブの実行とECS Execの検証

それではこの状態でジョブを実行してみましょう。ジョブの実行は作成したジョブ定義の画面のアクションから「新しいジョブを送信」で実行できます。

新しいジョブを送信するメニュー

適当に名前をつけ、作成したジョブキューを指定してジョブを送信します。

ジョブ送信の設定画面

しばらく待つと以下のようにジョブがRunnning状態になります。

実行中のジョブ状態表示

この状態で、ECS Execを試してみます。マネージメントコンソールの(AWS Batchではなく)ECSの画面を開き、クラスターの一覧を見るとAWS Batchが作成したECSクラスター(AWSBatch-〜)が存在しています。このECSクラスターをクリックし、タスクのタブから起動しようとしているタスクIDをコピーします。

ECSクラスターのタスク一覧画面

コピーしたタスク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の値を含むため、以下のようにジョブごとにフォルダが作成されてしまいますね。

S3バケットに出力されたログファイルの階層構造

ログの中身はこのような形です。"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に集約したいといったような要件にも対応できるようになったので、とても良いアップデートだと思います。

以上、とーちでした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.