2025年11月に追加されたECS Expressモードを触ってみたのでブログに残します。
ECS Expressモードとは
コンテナイメージを事前に用意しておけば、ECSクラスターやそれに紐づくALB、AutoScaling設定などを一括で作成してくれる設定です。
今までECSを使うにはALBやAutoScalingの他にもタスク定義の作成やセキュリティグループの設定など、ECSに慣れていない人からすると設定のハマりどころが多く存在しましたがECS Expressモードを使用すればそこら辺の設定がAWS側で行われるようです。
設定してみる
ということで設定を行ってみます。
ECS Expressモードは以下のドキュメントに記載されている通り、マネジメントコンソールだけでなくCloudFormationやTerraformなどのIaCからの作成もサポートしているようです。
今回はどこまで簡単に作成できるのか確認したいのでマネジメントコンソールから試してみます。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-overview.html#express-service-availability
ちなみに2025年12月現在、サポートしている作成方法は以下になります。
- The Amazon ECS console
- AWS AWS CLI
- AWS SDKs
- CloudFormation
- Terraform
- AWS Labs MCP Server for Amazon ECS
事前準備
コンテナイメージは事前に作成しておく必要があります。
以下のCloudFormationテンプレートを使用してECRを作成してください。
AWSTemplateFormatVersion: "2010-09-09"
Description: ECR
Metadata:
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Parameters for env Name
Parameters:
- env
Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
env:
Type: String
Default: dev
AllowedValues:
- dev
Resources:
# ------------------------------------------------------------#
# ECR
# ------------------------------------------------------------#
ECR:
Type: AWS::ECR::Repository
Properties:
EmptyOnDelete: true
EncryptionConfiguration:
EncryptionType: AES256
RepositoryName: !Sub ecr-${env}
ECR作成後、以下のDockerfileを使用してコンテナイメージを作成します。
index.htmlは好きなものを使用してください。
FROM public.ecr.aws/docker/library/httpd:2.4
COPY ./html/ /usr/local/apache2/htdocs/
以下のコマンドをCloudShellで実行するとECRまでプッシュができます。
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t ecr-dev .
docker tag ecr-dev:latest $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest
docker push $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest
ECS Expressモードでクラスターなどを作成していく
コンテナイメージが作成できたら以下のURLからECSコンソールへアクセスします。
https://ap-northeast-1.console.aws.amazon.com/ecs/v2/getStarted?region=ap-northeast-1
アクセス後、画面左のメニューから「Express モード」をクリックします。

クリックしたら「アプリケーションセットアップしましょう」の欄でイメージURL、タスク実行ロール、インフラストラクチャロールを設定します。

イメージURLはECRの画面から確認できますが、本ブログの手順でECRの作成とコンテナイメージを作成している場合は以下のようなURLになります。
AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest
タスク実行ロール、インフラストラクチャロールを事前に作成していない場合は「新しいロールの作成」をクリックするとIAMロールの作成画面へ移動して関連するロールが作成できます。
私のAWSアカウントではタスク実行ロールを過去に作成したことがあったので自動で選択されていました。
タスク実行ロールにはAmazonECSTaskExecutionRolePolicyというマネージドポリシーを設定しておけばECRからのプルが行えます。
子のコンソールからインフラストラクチャロールを作成するとAmazonECSInfrastructureRoleforExpressGatewayServicesというマネージドポリシーが設定されます。
AmazonECSInfrastructureRoleforExpressGatewayServicesの中身を見るとALBやセキュリティグループ、AutoScalingの作成に必要なポリシーが設定されており、ECSからリソースを作成するために必要な内容となっています。
「その他の設定」欄ではクラスターの選択やコンテナポート、VPCの設定などが行える欄になっています。
内容を見る限りではここがタスク定義に紐づく設定のようです。
今回は特に設定を変更せず、デフォルトのまま作成します。(下で設定できる内容を少し紹介します)

スケーリング設定を見るとCPU使用率、メモリ使用率、リクエスト数を使用したスケーリング条件を設定できるようです。

VPCの設定はデフォルトだとAWSアカウントのデフォルトVPCが自動で使用されるようです。
カスタマイズしたい場合は「ネットワーク設定をカスタマイズ」にチェックを入れると設定ができます。

ログ設定はCloudWatch Logsに出力できるようです。

設定が完了したら画面下の作成をクリックします。
作成をクリック後、以下の画像のようにリソースの作成状況が確認できます。

ECS Expressモードで作成されるリソースは以下のドキュメントに記載されています。
クラスターを削除すると一緒に削除されるようになっています。
動作確認
リソースの作成が完了後、アプリケーション URLからアクセスするとWebサイトが表示されます。

色々見てみる
クラスターは何も指定ていない場合、defaultというクラスター内に作成されています。

オブザーバビリティを見ると通常のECSと同じようにCPU使用率とメモリ使用率が確認できます。

下にスクロールするとALBに関連するメトリクスも確認できました。

サービスの更新はカナリアデプロイが使用されるようで (2025年12月現在それしか選べない?) 以下のドキュメントに動きが記載されていました。
-
Updating an Amazon ECS Express Mode service - Amazon Elastic Container Service
以下のように記載されており、最初に5%のトラフィックが新しいタスクに流れるようです。
その後、3分間待機して問題が無ければ100%トラフィックが新しいタスクに流れる動きになっています。
A new environment is created and tasks deployed with your changes
5% of traffic is shifted to the new environment
Alarm Based Rollbacks will trigger if sum of 4xx and 5xx errors percentage is > 1 for 2 datapoints within 3 minutes
Health checks verify the new tasks are healthy
After 3 minutes bake time, 100% of traffic is shifted to new environment
After 3 minutes bake time for monitoring, old tasks are gradually stopped and replaced
タスク定義の中身は以下のようになっており、最低限の設定のみ行われていました。
{
"compatibilities": [
"EC2",
"FARGATE",
"MANAGED_INSTANCES"
],
"containerDefinitions": [
{
"cpu": 1024,
"environment": [],
"essential": true,
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/aws/ecs/default/ecr-dev-1234-1234",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"memoryReservation": 2048,
"mountPoints": [],
"name": "Main",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"secrets": [],
"volumesFrom": []
}
],
"cpu": "1024",
"enableFaultInjection": false,
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"family": "default-ecr-dev-7d51",
"memory": "2048",
"networkMode": "awsvpc",
"placementConstraints": [],
"registeredAt": "2025-12-14T12:57:34.081Z",
"requiresAttributes": [
{
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
},
{
"name": "ecs.capability.execution-role-awslogs"
},
{
"name": "com.amazonaws.ecs.capability.ecr-auth"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
},
{
"name": "ecs.capability.execution-role-ecr-pull"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"name": "ecs.capability.task-eni"
}
],
"requiresCompatibilities": [
"FARGATE"
],
"revision": 1,
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
},
"status": "ACTIVE",
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/default-ecr-dev-7d51:1",
"volumes": [],
"tags": []
}
タスクが起動しているサブネットはパブリックサブネットになっており、パブリックIPアドレスも割り振られていました。
以下のドキュメントに記載されている通り、パブリックサブネットを選択すると自動でパブリックIPを割り振るようになっているようです。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-work.html#express-service-network-defaults
If you provide custom public subnets, Express Mode will provision an internet-facing ALB and turn on assignPublicIP for your tasks. If you provide private subnets (subnets without an internet gateway in their route table), Express Mode will provision an internal ALB.
作成されたALBはEC2のコンソールから確認することができます。
HTTPSリスナーが設定されたALBが作成されています。

リスナールールは以下のようになっており、ECSによって発行されたデフォルトのホスト名でアクセスしてきたらターゲットに流すように設定されていました。

カスタムドメインを使用したい場合は以下のドキュメントに記載されている通り、上記のリスナールールを編集するような形になるようです。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-advanced-customization.html#express-service-customization-examples:~:text=Adding%20a%20custom%20domain%20to%20your%20service
最後に
上記の手順の通り、簡単にコンテナアプリをデプロイできるのでECSに慣れていない人は使ってみるのがよいかもしれません。
気になる部分としてはネットワーク部分の設定になります。
ここら辺はタスクとALBで分ける (パブリックサブネットとプライベートサブネット) ようにできたらかなりよさそうです。
