Amazon ECS Express Modeの新機能「カスタムタスク定義」で、ARM64・サイドカー・FireLensを試してみた

Amazon ECS Express Modeの新機能「カスタムタスク定義」で、ARM64・サイドカー・FireLensを試してみた

2026年7月、Amazon ECS Express Modeでカスタムタスク定義を指定できるようになりました。本記事では、ARM64(Graviton)、サイドカーコンテナ、コンテナヘルスチェック、FireLensによるS3ログ出力を、Express Modeの自動インフラ管理を維持したまま利用できることを検証します。
2026.07.02

はじめに

2026年7月1日、Amazon ECS Express Modeがカスタムタスク定義に対応するアップデートがリリースされました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/07/amazon-ecs-express-mode-custom-task-def/

従来のExpress Modeは、タスク定義を自動生成する仕組みのため、CPUアーキテクチャの指定やサイドカーコンテナの追加ができませんでした。今回のアップデートにより、ユーザーが作成したタスク定義を渡せるようになりました。Express Modeの自動インフラ管理(ALB、オートスケーリング、カナリアデプロイ等)の恩恵を受けながら、タスク定義レベルの柔軟な設定が可能です。

以下に、従来と今回のアップデート後の比較をまとめます。

項目 従来のExpress Mode カスタムタスク定義対応後
CPUアーキテクチャ x86_64固定 ARM64指定可能
サイドカー 不可 可能
コンテナヘルスチェック Express Modeの --health-check-path のみ タスク定義レベルで自由に定義可能
ログルーティング CloudWatch Logs固定 FireLens利用可能
ulimits/Linuxランタイム設定 不可 可能
既存タスク定義の再利用 不可 要件を満たせば流用可能

以前、Express Modeのアーキテクチャ制約を回避するワークアラウンドを紹介しましたが、今回のアップデートでこれらの手順は不要になりました。

https://dev.classmethod.jp/articles/ecs-express-mode-arm64-fargate-spot-exec/

本記事では、カスタムタスク定義を使ってARM64、サイドカー、カスタムヘルスチェック、FireLensの4機能をExpress Modeで動作させる検証を行いました。

カスタムタスク定義の要件

Express Modeにカスタムタスク定義を渡す場合、タスク定義は以下の要件を満たす必要があります。

  • コンテナ名 Main が必須
  • Main コンテナにname付きの単一TCPポートマッピング(containerPort + portMappings[].name)が必要
  • requiresCompatibilitiesFARGATE を指定すること

また、create-express-gateway-service--task-definition-arn を指定する場合、以下のパラメータは同時に指定できません(すべてタスク定義側で定義します)。

  • --primary-container
  • --execution-role-arn
  • --task-role-arn
  • --cpu
  • --memory

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-getting-started.html

検証環境

  • リージョン: ap-northeast-1
  • ECSクラスター: default
  • コンテナイメージ: ARM64ビルドのGoアプリ(ECR)— :8080でHTTPサーバーを提供
  • IAMロール: ecsTaskExecutionRole(タスク実行ロール)、ecsInfrastructureRoleForExpressServices(インフラストラクチャロール)

ARM64タスク定義でExpress Modeサービスを作成する

ARM64(Graviton)で動作するタスク定義を登録し、Express Modeサービスを作成しました。

タスク定義

{
  "family": "express-mode-custom-td",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "runtimePlatform": {
    "cpuArchitecture": "ARM64",
    "operatingSystemFamily": "LINUX"
  },
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "Main",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/express-mode-custom-td:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp",
          "name": "http"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/express-mode-custom-td",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "main"
        }
      }
    }
  ]
}

ポイントは runtimePlatformcpuArchitecture: ARM64 を指定している点です。

Express Modeサービスの作成

aws ecs register-task-definition --cli-input-json file://td-arm64.json

aws ecs create-express-gateway-service \
  --infrastructure-role-arn arn:aws:iam::123456789012:role/ecsInfrastructureRoleForExpressServices \
  --task-definition-arn arn:aws:ecs:ap-northeast-1:123456789012:task-definition/express-mode-custom-td:1 \
  --health-check-path "/health" \
  --monitor-resources

サービスがACTIVEになり、エンドポイントが発行されました。

https://ex-99879651ad6c475e9537a5c5e0bcc347.ecs.ap-northeast-1.on.aws

動作確認

エンドポイントにアクセスすると、ARM64で動作していることが確認できました。

$ curl https://ex-99879651ad6c475e9537a5c5e0bcc347.ecs.ap-northeast-1.on.aws/
Hello from Express Mode! arch=arm64 hostname=ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal

describe-tasks でもアーキテクチャを確認しました。

{
  "attributes": [
    {
      "name": "ecs.cpu-architecture",
      "value": "arm64"
    }
  ]
}

サイドカーコンテナを追加する

タスク定義(サイドカー追加部分)

{
  "name": "datadog-agent",
  "image": "public.ecr.aws/datadog/agent:latest",
  "essential": false,
  "secrets": [
    {"name": "DD_API_KEY", "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:datadog-api-key"}
  ],
  "environment": [
    {"name": "ECS_FARGATE", "value": "true"},
    {"name": "DD_APM_ENABLED", "value": "true"}
  ],
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "/ecs/express-mode-custom-td",
      "awslogs-region": "ap-northeast-1",
      "awslogs-stream-prefix": "sidecar"
    }
  }
}

本検証では、Datadog Agentが停止してもMainコンテナを継続させるため essential: false に設定しています(用途に応じて値は変わり、後述のFireLensのlog-routerは essential: true とします)。Express Modeのトラフィックルーティングとヘルスチェックは Main コンテナに対して動作します。

動作確認

update-express-gateway-service でサイドカー付きタスク定義に更新しました。

aws ecs update-express-gateway-service \
  --service-arn arn:aws:ecs:ap-northeast-1:123456789012:service/default/express-mode-custom-td-f9de \
  --task-definition-arn arn:aws:ecs:ap-northeast-1:123456789012:task-definition/express-mode-custom-td:2

タスク内のコンテナ一覧を確認すると、Mainとdatadog-agentの両方がRUNNINGでした。

{
  "containers": [
    {
      "name": "Main",
      "lastStatus": "RUNNING"
    },
    {
      "name": "datadog-agent",
      "lastStatus": "RUNNING"
    }
  ]
}

Express Modeのエンドポイントは引き続き正常に応答し、ALBやオートスケーリング等の管理機能への影響はありませんでした。

カスタムコンテナヘルスチェックを定義する

Express ModeのALBヘルスチェック(--health-check-path)と、タスク定義レベルのコンテナヘルスチェックは異なるレイヤーを制御します。ALBヘルスチェックはターゲットグループ上のヘルス判定とルーティング可否に、コンテナヘルスチェックはECSのタスクヘルスステータスに反映されます(コンテナヘルスチェックの失敗はタスク置き換えにつながり、結果的にターゲットの入れ替わりにも波及します)。両者が共存できることを確認しました。

タスク定義(ヘルスチェック部分)

{
  "name": "Main",
  "healthCheck": {
    "command": ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"],
    "interval": 10,
    "timeout": 5,
    "retries": 3,
    "startPeriod": 5
  }
}

動作確認

タスク定義レベルのコンテナヘルスチェックが動作し、describe-taskshealthStatus: HEALTHY を確認しました。

{
  "lastStatus": "RUNNING",
  "healthStatus": "HEALTHY",
  "containers": [
    {
      "name": "Main",
      "lastStatus": "RUNNING",
      "healthStatus": "HEALTHY"
    }
  ]
}

FireLens(Fluent Bit)でS3にログを出力する

FireLens構成のタスク定義(リビジョン5)を登録し、update-express-gateway-service で更新しました。サービス更新後、Mainとlog-routerの両コンテナがRUNNINGになり、S3バケットにログが出力されました。

$ aws s3 ls s3://your-log-bucket/ --recursive
2026-07-02 10:05:05  248 logs/Main-firelens-707e0a68.../2026/07/02/01/04/c2N7RBVd.gz

ログの内容を確認すると、ECSメタデータが自動付与されていました。

{
  "date": "2026-07-02T01:04:33.427703Z",
  "container_id": "707e0a68...",
  "container_name": "Main",
  "source": "stdout",
  "log": "Starting server on :8080",
  "ecs_cluster": "default",
  "ecs_task_arn": "arn:aws:ecs:ap-northeast-1:123456789012:task/default/707e0a68...",
  "ecs_task_definition": "express-mode-custom-td:5"
}

enable-ecs-log-metadata: true を設定したことで、クラスター名、タスクARN、タスク定義名が各ログレコードに付与されます。

構成のポイント

  • Main コンテナの logConfigurationlogDriver: awsfirelens を指定し、出力先としてS3プラグインを設定
  • log-router コンテナに firelensConfiguration を定義し、Fluent Bitをログルーターとして起動
  • MaindependsOnlog-routerを先に起動する順序を明示する(本検証ではSTARTを指定。起動直後のログ取りこぼしをより確実に避けたい場合は、log-routerにヘルスチェックを定義しHEALTHYを指定する)
  • タスクロールへS3のPutObject権限を付与する
  • Fluent Bitのイメージは public.ecr.aws/aws-observability/aws-for-fluent-bit:latest(マルチアーチ対応のためARM64でも動作する)
タスク定義全文
{
  "family": "express-mode-custom-td",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "runtimePlatform": {
    "cpuArchitecture": "ARM64",
    "operatingSystemFamily": "LINUX"
  },
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsExpressModeTaskRole",
  "containerDefinitions": [
    {
      "name": "Main",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/express-mode-custom-td:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp",
          "name": "http"
        }
      ],
      "healthCheck": {
        "command": ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"],
        "interval": 10,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 5
      },
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "options": {
          "Name": "s3",
          "region": "ap-northeast-1",
          "bucket": "your-log-bucket",
          "total_file_size": "1M",
          "upload_timeout": "30s",
          "s3_key_format": "/logs/$TAG/%Y/%m/%d/%H/%M/$UUID.gz",
          "compression": "gzip"
        }
      },
      "dependsOn": [
        {
          "containerName": "log-router",
          "condition": "START"
        }
      ]
    },
    {
      "name": "log-router",
      "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:latest",
      "essential": true,
      "firelensConfiguration": {
        "type": "fluentbit",
        "options": {
          "enable-ecs-log-metadata": "true"
        }
      },
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/express-mode-custom-td",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "firelens"
        }
      }
    }
  ]
}

タスク定義更新時のデプロイ動作

update-express-gateway-service でタスク定義の新リビジョンを指定すると、Express Modeのデプロイ戦略(カナリア)が適用されます。

aws ecs update-express-gateway-service \
  --service-arn arn:aws:ecs:ap-northeast-1:123456789012:service/default/express-mode-custom-td-f9de \
  --task-definition-arn arn:aws:ecs:ap-northeast-1:123456789012:task-definition/express-mode-custom-td:6

今回の検証では、カナリアタスク(約5%)起動 → ベイクタイム(約3分)→ 残タスク置き換え → ベイクタイム(約3分)→ 旧タスク停止、という流れが観測されました。デプロイ中もエンドポイントは継続して応答しました。

$ curl https://ex-99879651ad6c475e9537a5c5e0bcc347.ecs.ap-northeast-1.on.aws/
Hello from Express Mode v2! arch=arm64 hostname=ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal

まとめ

ECS Express Modeのカスタムタスク定義対応により、「CLIひとつでALB・オートスケーリング・カナリアデプロイが揃う簡単さ」と「タスク定義による柔軟な設定」を両立できるようになりました。

本記事では、ARM64(Graviton)、サイドカーコンテナ、コンテナヘルスチェック、FireLensによるS3ログ出力を、Express Modeの自動インフラ管理を維持したまま利用できることを確認しました。

Express Modeでシンプルにサービスを作成しつつ、タスク定義でコンテナ構成やログルーティングを細かく制御したい場合に、有用なアップデートです。

参考リンク

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事