はじめに
この記事はClaudeと一緒に書きました
Xで「cdk deployが最大15倍速くなる」というツールが流れてきました。
CDKアプリはそのまま、cdk deployをcdkd deployに置き換えるだけとのことです。
それを確かめるために、今回は自分でも実際にAWSへデプロイして時間を測ってみました。
結論から言うと、めっちゃ速かったです
cdkdとは
cdkdは、既存のAWS CDKアプリをCloudFormationを経由せず、AWS SDKで直接デプロイするCLIツールです。
- CDKアプリのコードは一切変更不要
-
cdk deployと打つところをcdkd deployに変えるだけ - 本番はCloudFormation、開発中だけcdkdという併用が前提
作者について
作者はgo-to-kさん(AWS DevTools Hero、AWS CDK Top Contributor)です。
S3バケットを高速に空にするcls3や、CloudFormation/CDKスタックの削除に強いdelstackなど、AWSの「かゆいところ」に手が届くツールを作り続けている方という印象があります。
cdkdはその集大成のひとつという感じで、開発体験に効くツールをきっちり形にしてくれています。
ありがとうございます。
仕組み
CDKアプリを合成(synth)して出てくるCloudFormationテンプレートまではCDK CLIと同じものを使います。
違うのはそこから先です。
- cdk deploy: テンプレートをCloudFormationに渡し、CloudFormationがリソースを1つずつ順番に作る
- cdkd deploy: テンプレートの依存関係(
RefやFn::GetAtt)を自分で解析してDAGを組み、依存が揃ったリソースからAWS SDK / Cloud Control APIを直接・並列に叩く
念のため書いておくと、cdkd自身が「production-ready ではない、開発・テスト用」と明言しているツールです。
本番運用中のスタックをいきなり乗り換える話ではありません。
実際にデプロイして計測してみた
「最大15倍」はcdkd自身のベンチマークの数字で、VPC + Lambda + SQS + CloudFrontという構成での計測結果が載っていました。
せっかくなので同じ構成のCDKアプリを自分で書いて、実際にAWSへデプロイしてみました。
テスト用スタック
DeployRaceCfn(cdk deploy用)とDeployRaceCdkd(cdkd deploy用)という同一構成の2スタックを、同じAWSアカウント・同じリージョン(ap-northeast-1)に用意しました。
- VPC(2AZ + NATゲートウェイ) + Lambda(VPC内、Function URL付き)
- CloudFront(オリジンはFunction URL)
- SQS + EventSourceMapping + Consumer Lambda
構成図にするとこうなります。
1回目は失敗
デプロイを始めてすぐ、アカウントのVPC上限(デフォルト5個)に引っかかって1回失敗しました。
Resource handler returned message: "The maximum number of VPCs has been reached.
(Service: Ec2, Status Code: 400, ...)"
他の検証用スタックでVPCを使い切っていたのが原因でした。
cdkd deploy側を先にcdkd destroyして枠を空けてからやり直しました。
cdkdは実行のたびにcdkd eventsという構造化イベントログをS3に残してくれます。
失敗した1回目もどこで何が失敗したか後から普通に追えたので、助かりました。
計測方法
デプロイフェーズのみを比較しています。cdk synthはどちらも同じaws-cdk-libを通る同一処理なので、cdkd自身のベンチマーク手法にならって除外しました。
- cdk deploy側: CloudFormationの
DescribeStackEvents - cdkd deploy側:
cdkd events <stack> --run <id> --format json(RESOURCE_STARTED/RESOURCE_SUCCEEDEDイベント)
それぞれのスタック作成開始〜完了までを実測しています。
結果
| cdk deploy | cdkd deploy | |
|---|---|---|
| 所要時間 | 479.3秒 | 95.0秒 |
| 作成リソース数 | 34個 | 33個 |
5.0倍速でした。差の1個はCloudFormation側だけに乗る記録用のAWS::CDK::Metadataで、実質は同じ33リソースを両者が作っています。
ログを見比べる
cdkd deployの実行ログを見ると、開始してすぐにIAMロールやルートテーブルが横並びで完成していきます。
[1/33] ✓ RaceQueueE818AC65 (AWS::SQS::Queue) created
[2/33] ✓ RaceVpcIGW94C1C01D (AWS::EC2::InternetGateway) created
[3/33] ✓ RaceVpcPublicSubnet1EIPC3B3497E (AWS::EC2::EIP) created
[4/33] ✓ ConsumerFunctionServiceRole68E8FEB1 (AWS::IAM::Role) created
[5/33] ✓ MainFunctionServiceRole8C918DF0 (AWS::IAM::Role) created
...
CloudFront Distribution Distribution830FAC52 accepted (not waiting for Deployed; pass --full-wait to wait)
Deployment Summary:
Created: 33 / Duration: 94.99s
一方cdk deploy側は、VPCが1個できるまでにもう16.6秒かかっていて、この時点でcdkdはとっくにLambdaとSQSの接続まで終えていました。
実測タイムラインをそのまま再生できるページも作ったので、両者の進み方の違いはこちらのほうがわかりやすいかもしれません。
なぜここまで差がつくのか
CloudFormationという仲介者を経由するかどうかが、そのままレイテンシの差になっています。今回の計測で差が大きかったポイントは、次の2つです。
NATゲートウェイ待ちの順番
cdk deploy側はSQS・Lambdaまわりを片付けてからNATゲートウェイの起立を待つ順番でした。cdkd側は早い段階でNATゲートウェイの起立待ちに入っていました。
並列実行のスケジューリング次第で、「待ち時間」をどこに前借りできるかが変わってくるという話でもあります。
CloudFrontの待ち方の違い
CloudFormationはデフォルトで「配信が完全にDeployedになるまで」待ちます。これに3分以上かかります。
cdkdはデフォルトでCreateDistributionが受理された時点で完了扱いにします(--full-waitを渡せばCloudFormationと同じ挙動にできます)。
今回の479.3秒のうち、実に183秒(3分強)がこのCloudFront待ちだけで消えていました。
この2つの経路の違いを図にすると、こうなります。
cdkdはデフォルトでCreateDistributionが受理された時点で完了扱いにします(--full-waitを渡せばCloudFormationと同じ挙動にできます)。
今回の479.3秒のうち、実に183秒(3分強)がこのCloudFront待ちだけで消えていました。
デプロイ戦略、変わるかもしれない
正直なところ、「AWSでコード書いてすぐ試したい」ときの遅さが、VercelやAmplifyを選ぶ理由の一つになっている実感があります。
CDKでVPC+Lambda+CloudFrontみたいな構成を作ると、確認のたびに数分〜十数分待たされるのがイテレーションの足を引っ張ります。
cdkdはあくまでdev/test用と明言されていますし、CloudFormationの状態管理・ドリフト検出・ロールバックといった機能を丸ごと肩代わりするわけでもありません。
それでも、「本番はCloudFormation、開発中だけcdkd」という併用が現実的な選択肢として提示されたのは大きいと思います。
PR環境を毎回作り直すCI、あるいは手元でのapply→確認のループが今の数分の1になるなら、「AWSネイティブな構成だとVercel/Amplifyより遅い」という前提そのものが崩れてくる人も出てくるはずです。
終わりに
実況付きのデモ動画も作りました。よかったら覗いてみてください。
最後まで読んでいただきありがとうございました。



