5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS CDK】Expressモードでリソースデプロイが最大4倍速くなるらしいので試してみた

5
Last updated at Posted at 2026-07-19

はじめに

2026年6月30日のアップデートで、CloudFormation/CDK/SAMにExpressモードが追加されました。

リソースの安定化を待たずにスタック操作を完了扱いにするモードで、内部ベンチマークでは最大4倍速くなるとのことです。コードの改修などは必要なく、CDKならcdk deploy --expressを付けるだけで使えます。

本記事では仕組みと制約を整理し、通常モードとデプロイ時間を実測で比較します。

本記事の情報は2026年7月時点のものです。
最新情報については公式ドキュメントをご確認ください。

この記事でわかること

  • Expressモードの仕組み(何を待たなくなるのか)
  • cdk deploy --expressの使い方と必要なCLIバージョン
  • 通常モードとの実測比較(公式ベース/CloudFront/サーバレスの3パターン)
  • rollbackがデフォルト無効になる点など、注意点と使いどころ

先に結論

項目 通常モード Expressモード
デプロイ完了の条件 リソースが安定状態に達するまで待つ 設定APIが成功した時点で完了扱い
失敗時のrollback 自動でrollbackされる デフォルト無効("disableRollback": falseで有効化)
推奨用途 本番デプロイ 開発中のイテレーション

実測は、安定化待ちの長さが違う3パターンのスタックで行いました。

検証パターン 通常モード Expressモード
A. SQS+DLQ(公式ベンチマーク再現) 72.51秒 10.94秒
B. S3+CloudFront 210.34秒 46.75秒
C. サーバレス(API Gateway+Lambda+DynamoDB) 41.7秒 26.2秒

公式ブログのベンチマークでは、SQS+DLQの作成が64秒から10秒以下に、ENI付きLambda関数の削除が20〜30分から10秒以下になったと紹介されています(参考)

1. Expressモードとは

公式ドキュメントの説明は以下のとおりです。

In the default deployment mode, CloudFormation waits for each resource to reach a fully stabilized state before reporting the resource as complete. For example, when creating an Amazon EC2 instance, CloudFormation waits until the instance is in the running state.
In express mode, CloudFormation typically considers a resource operation complete as soon as the API call to create, update, or delete the resource succeeds. In most cases, CloudFormation does not wait for the resource to reach its final operational state.

(和訳)Expressモードでは、CloudFormationは通常、リソースの作成、更新、または削除を行うAPI呼び出しが成功するとすぐに、リソース操作が完了したとみなします。ほとんどの場合、CloudFormationはリソースが最終的な運用状態に達するまで待機しません。

ひとことで言うと、リソースが出来上がるまで見届けるのをやめて、作成指示が通ったら次へ進むモードのようです。

Before: 通常モードは安定化を待つ

従来のCloudFormationは、各リソースが安定状態に達するまで次へ進みません。EC2インスタンスならrunningになってステータスチェックが通るまで、CloudFrontなら世界中のエッジロケーションへ設定が行き渡るまで待ちます。確実ですが、この待ち時間がdeploy全体を長くしていました。

After: 設定APIの成功=完了扱い

Expressモードでは、設定を適用するAPI呼び出しが成功した時点でそのリソースは完了扱いになります。つまり、deployが完了と表示された時点でも、裏ではリソースの初期化が続いていることがあります。公式ドキュメントには、リソース種別ごとの具体例が表で載っています。

リソース 操作 完了報告後に起きうること
CloudFrontディストリビューション 作成/更新 グローバルへの配信反映に数分かかることがある
EC2インスタンス 作成 ユーザーデータの実行やステータスチェックがまだ進行中のことがある
Lambda関数 削除 削除完了の報告後もクリーンアップが続くことがある
ECSサービス 作成/更新 タスクの起動や安定化がまだ続いていることがある

依存関係とOutputsの扱い

リソース間の依存関係(Ref / Fn::GetAtt)の順序は従来どおり守られます。
公式ドキュメントにも次のように明記されています(和訳)。

Express mode does not change the dependency ordering of your resources. It changes when the stack operation reports complete.

(和訳)Expressモードはリソースの依存関係の順序を変更しません。変わるのは、スタック操作が完了を報告するタイミングです。

また、スタックのOutputsでリソースの属性を参照している場合、CloudFormationはその属性値を読み取るためにリソースの伝播を待ちます(トラブルシューティングガイドに記載)。
「Expressモードなら全部待たなくなる」わけではないので注意が必要です。

2. hotswapとの違い

CDK CLIには--hotswapというオプションがあります。これもデプロイを速くする機能ですが、CloudFormationを介さずにリソースをSDKで直接更新します。そのぶん、デプロイ済みのスタックの状態と実環境の間にドリフトが起きうる点に注意が必要です。Expressモードは通常のCDK deployと同じくCloudFormation経由なので、ドリフトの心配はありません。

以下、Expressモードとhotswapでのデプロイについての比較です。(参考:公式ドキュメント)

項目 Expressモード CDK hotswap
デプロイの仕組み すべてCloudFormation経由 CloudFormationを迂回してサービスAPIを直接呼ぶ
テンプレート互換性 既存のテンプレートすべてで動く 対応リソースが限られる
スタックの状態 テンプレートと一貫性を保つ テンプレートからドリフトしうる
rollback 対応(デフォルト無効) 非対応
対応リソース CloudFormationの全リソースタイプ 限定的(Lambda、ECS、Step Functionsなど)
推奨用途 開発・イテレーション 対応リソースのみの開発ワークフロー

3. 検証環境と検証内容

Expressモードと通常モードでのデプロイ速度を比較するために実機での検証を行いました。

検証環境

項目 内容
aws-cdk(CLI) v2.1132.0
aws-cdk-lib v2.261.0
Node.js v22.20.0
リージョン ap-northeast-1(東京)

--expressフラグはaws-cdk(CLI)のv2.1129.0(2026年7月1日リリース)で追加されました。deployだけでなくdestroyとbootstrapでも使えます。

前提条件

  • AWS認証情報が設定済みであること
  • 検証リージョンでcdk bootstrapが実行済みであること
  • aws-cdk(CLI)がv2.1129.0以上であること

検証内容

Expressモードの効果は安定化待ちの長さで決まるはずなので、性格の違う3パターンのスタックを用意して、通常モードとExpressモードでそれぞれデプロイ時間を計測します。

パターン 構成 ねらい
A SQS+DLQ 公式ベンチマーク(64秒→10秒以下)と同じ構成で数字を突き合わせる
B S3+CloudFront エッジロケーションへの伝播待ちが長い代表格
C API Gateway+Lambda+DynamoDB 安定化待ちが少ないサーバレス構成。効果がどこまで出るかを見る対照群
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';

/**
 * パターンA: SQS+DLQ。
 * 公式ベンチマークと同じ構成で、公表値と自環境の数字を突き合わせる。
 */
export class ExpressBenchSqsStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // デッドレターキュー
    const dlq = new sqs.Queue(this, 'Dlq');

    // メインキュー(3回失敗したメッセージをDLQへ退避)
    new sqs.Queue(this, 'MainQueue', {
      deadLetterQueue: { queue: dlq, maxReceiveCount: 3 },
    });
  }
}

/**
 * パターンB: S3+CloudFront。
 * 通常モードではエッジへの伝播完了まで待たされる。
 */
export class ExpressBenchCloudFrontStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'OriginBucket');
    new cloudfront.Distribution(this, 'Distribution', {
      defaultBehavior: {
        origin: origins.S3BucketOrigin.withOriginAccessControl(bucket),
      },
    });
  }
}

/**
 * パターンC: API Gateway+Lambda+DynamoDB。
 * 安定化待ちがほとんどないサーバレス構成の対照群。
 */
export class ExpressBenchServerlessStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.TableV2(this, 'Table', {
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
    });

    // 計測用なので中身は最小限
    const fn = new lambda.Function(this, 'Handler', {
      runtime: lambda.Runtime.NODEJS_22_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200 });'),
      environment: { TABLE_NAME: table.tableName },
    });

    new apigateway.LambdaRestApi(this, 'Api', { handler: fn });
  }
}

デプロイ時間は、cdk deployが完了時に出力するDeployment timeを記録します。これはCloudFormationのデプロイにかかった時間で、synthを含むTotal timeとは別に表示されます。ばらつきを見るため各パターン3回ずつ実行し、検証が終わったスタックはcdk destroyで削除します。

4. 通常モードでデプロイ(Before)

まずは従来どおりのデプロイです。3パターンを順に流します。

# 通常モードで各パターンをデプロイ
$ cdk deploy ExpressBenchSqsStack
$ cdk deploy ExpressBenchCloudFrontStack
$ cdk deploy ExpressBenchServerlessStack

デプロイが終わるとDeployment timeが出力されます(SQSパターンの例)。通常モードでは特に注意書きは出ません。

✅  ExpressBenchSqsStack

✨  Deployment time: 72.51s

✨  Total time: 89.95s

3パターンの結果は次のとおりです(各パターン3回実行した平均実行時間を掲載)。

パターン Deployment time(通常モード)
A. SQS+DLQ 72.51秒
B. S3+CloudFront 210.34秒
C. サーバレス 41.7秒

5. Expressモードでデプロイ(After)

3パターンのスタックを一度削除して、今度は--express付きでデプロイします。
フラグを1つ足すだけで、テンプレート側の変更は不要です。ちなみに削除にもcdk destroy --expressが使えます。

# Expressモードで各パターンをデプロイ
$ cdk deploy ExpressBenchSqsStack --express
$ cdk deploy ExpressBenchCloudFrontStack --express
$ cdk deploy ExpressBenchServerlessStack --express
パターン Deployment time(Expressモード) 通常モード比
A. SQS+DLQ 10.94秒 約6.6倍
B. S3+CloudFront 46.75秒 約4.5倍
C. サーバレス 26.2秒 約1.6倍

安定化待ちが長いSQSとCloudFrontは、通常モードの4〜7分の1まで縮みました。特にSQSは公式ベンチマークの「64秒→10秒以下」ともよく一致しています。一方で、安定化待ちがほとんどないと踏んでいたサーバレス構成も1.6倍速くなり、「差は出ないだろう」という当初の予想は外れました。IAMロールなど小さな安定化待ちの積み重ねでも、それなりに効くようです。

デプロイ完了時の表示

Expressモードでデプロイすると、CLIの完了メッセージに警告が出ました(SQSパターンの例)。まだ安定化していないリソースの論理IDが並びます。

✅  ExpressBenchSqsStack

✨  Deployment time: 10.94s

⚠️  Stack deployed using Express Mode. Resources still stabilizing: DlqD1FAA4AD, MainQueueD24C6076

deployは完了扱いなのに、裏ではまだ安定化中、という状態がそのまま表示されるわけです。通常モード(Before)の出力にこの警告が無いのと対照的です。

CloudFormationコンソール側でも、スタックの「状況の理由」にExpressモードで完了した旨が記録されます。

Stack operation completed using Express Mode. Resources may continue becoming available in the background.

image.png

他の方の検証記事

IAM RoleやEC2インスタンスを含む構成では、通常モードの183秒がExpressモードで40秒(約4.6倍)になったという結果も出ています。ボトルネックはInstanceProfileの安定化待ち(2分11秒→1秒)だったそうです。詳しくはこちらのsuzuki.ryoさんの記事をご参照ください。

6. 注意点

rollbackがデフォルト無効になる

Expressモード最大の注意点です。公式ドキュメントには次のようにあります(和訳)。

Expressモードを使うと、CloudFormationはデフォルトでrollbackを無効にします。リソース操作が失敗しても、変更を自動では巻き戻しません。

rollbackを再有効化する方法は、CDKとAWS CLIでフラグの形が異なります。

ツール rollbackの再有効化
CDK cdk deploy --express --rollback
AWS CLI --deployment-config '{"mode": "EXPRESS", "disableRollback": false}'
# CDK: Expressモード+rollback有効
cdk deploy --express --rollback

# AWS CLI: deployment-configのJSONで指定する
aws cloudformation create-stack --stack-name my-stack \
  --template-body file://my-template.yaml \
  --deployment-config '{"mode": "EXPRESS", "disableRollback": false}'

rollbackされないまま失敗すると、リソースがそのまま残り、次のデプロイ時に失敗したリソースから再開するようです(参考:ロールバックを無効にする)

公式では「リソースの完全な安定化を確認する必要がある本番デプロイには、通常モードを使うこと」を推奨しています。Expressモードは本番環境でも技術的には使えてしまう(機能として禁止されていない)ため、運用ルールとして「本番は通常モード」を決めておくのが安全です。

deploy完了直後はリソースが未安定な場合がある

1章の設定apiの成功完了扱いのとおり、完了報告の裏でリソースの初期化が続いていることがあります。deploy直後に結合テストを叩くCIパイプラインだと、リソースがまだ出来上がっておらずテストが不安定になる、という形で踏みそうです。

削除でも同様で、destroy完了後に実際のクリーンアップが終わる前に同名リソースでスタックを作り直すと名前衝突が起きうる、とトラブルシューティングガイドに書かれています。destroyとcreateを素早く繰り返すCI/CD構成では注意が必要です。

その他の制約

項目 内容
StackSets 非対応
カスタムリソース Expressモードでも従来どおり応答を待つ。ServiceTimeoutの設定が推奨
ネストスタック 親スタックの設定が全ネストスタックに伝播(個別指定は不要)
料金 追加料金なし
対応リージョン 全商用リージョン ※GovCloud・中国リージョンの扱いは明言なし

カスタムリソース中心のスタックでは恩恵が薄めです。またServiceTimeoutを設定していないと、遅いカスタムリソースがExpressモードのメリットを打ち消してしまいます。

動作確認

動作確認結果

検証項目 期待する挙動 結果
--expressでdeployが成功する 通常と同じくデプロイが完了する
安定化待ちが長い構成で大きく短縮される パターンA・Bで通常モードの4〜7分の1
安定化待ちが少ない構成でも短縮される パターンCでも約1.6倍

まとめ

本記事では、CloudFormation/CDKに追加されたExpressモードの仕組みを整理し、安定化待ちの長さが違う3パターンのスタックで通常モードとのデプロイ時間を比較しました。

CloudFormation経由のままドリフトの心配なく速くなる、というのがhotswapとの一番の違いで、開発中のスタックには常用したいと感じています。一方でrollbackがデフォルト無効になる点、deploy完了直後はリソースが未安定な場合がある点は頭に入れておく必要があります。本番は従来どおり通常モード、開発イテレーションはExpressモード、という使い分けに落ち着きそうです。

今後はCIパイプラインのデプロイ時間短縮にもExpressモードを試してみたいと思います。参考になれば幸いです。

参考

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?