はじめに
PR を作るたびに本番同等のクラウド環境が立ち上がるようにしたのですが、なんだか構築時間がやたらとかかっているご様子。
実測でボトルネック特定 → シンプル修正 で 318秒 → 249秒(-70秒) 実現した話です。
このシステムの構成
本番環境
api.example.com
CloudFront (CDN) ──→ S3 (静的ファイル)
↓
API Gateway + Lambda (バックエンド)
↓
RDS PostgreSQL
PR プレビュー環境
同じ構成が PR 毎に新規生成されます:
pr-123.preview.example.com
CloudFront ──→ S3 ← 毎回新規作成
↓
API Gateway + Lambda ← 毎回新規作成
↓
RDS PostgreSQL (共有DB を複数 PR で分離)
ポイント:CloudFront・S3・Lambda は PR 毎に新規、DB は共有
問題:何に時間がかかってる?
ワークフロー全体:約 6 分 40 秒
| 処理 | 時間 |
|---|---|
| ビルド・準備 | 65s |
| cdk deploy | 318s ← ここ |
| その他 | 15s |
CDK deploy が 80% 占めてる。詳しく見ると?
分析:CloudFormation ログで追跡
リソース生成のタイムライン(実測):
時刻 イベント
─────────────────────────────────────
3:39:38 CloudFront 作成開始
3:39:58 S3 アップロード開始(← Distribution より 20 秒後)
3:41:03 S3 アップロード完了 [85 秒]
3:42:25 CloudFront 完了 [166 秒]
見える問題
CloudFront: ████████████████████████ [166s]
S3 Upload: ████ [85s]
S3 アップロードが Distribution の 後ろにぶら下がっている → この 85 秒が丸ごと無駄
原因:CloudFront の無効化待ち
現在のコード:
new s3deploy.BucketDeployment(...{
distribution, // ← CloudFront への依存
distributionPaths: ["/*"], // ← キャッシュ全削除
});
/* 無効化は CloudFront が完全に立ち上がるまで待つ必要あり。
だから S3 アップロード(BucketDeployment)も待たされてた。
解決:キャッシュ戦略を変える
無効化をやめて、HTML に「キャッシュするな」ヘッダ付与 に変更。
コードの修正
- new s3deploy.BucketDeployment(...{
- distribution,
- distributionPaths: ["/*"],
- });
+ new s3deploy.BucketDeployment(...{
+ cacheControl: [s3deploy.CacheControl.fromString("no-cache")],
+ });
これだけ。
何が変わるか
【改善後】
CloudFront: ████████████████████████ [166s]
S3 Upload: ████ [85s] ← 並列実行
計: ████████████████████████ [166s] ← CloudFront の時間のみ
Distribution と S3 が並列になり、全体時間は 166 秒 に短縮。
CloudFront は HTML の no-cache を尊重するので、常に最新を配信。ハッシュ付き JS/CSS はキャッシュ OK。
Tier 2:2回目以降をさらに高速化
ワークフロー 1 行追加:
cdk deploy --hotswap-fallback
初回はフルデプロイ(249 秒)。
2 回目以降は Lambda・HTML だけ直接更新(20~30 秒)。
CloudFront 変更あれば自動でフルデプロイに切り替わる。
実績
Before
cdk deploy: 318秒
- CloudFront 作成: 158秒
- S3 アップロード: 90秒 ← 直列化されてた
- 他: 70秒
合計: 398秒(6分38秒)
After
cdk deploy: 249秒 (-69秒)
- CloudFront 作成: 166秒
- S3 アップロード: 85秒で完了 ← 並列、後ろに積まれない
合計: 329秒(5分29秒)
CloudFormation ログで並列化を確認:
3:39:38 Distribution 開始 ────┐
3:39:58 Upload 開始 ──────────┤ 同時実行
3:41:03 Upload 完了 │
3:42:25 Distribution 完了 ────┘
Upload は Distribution より 82 秒前に完了 ✓
月間効果
開発者 5 名、月 100 PR(各 3 回のプッシュ)の場合:
Before: 5 × 100 × 3 × 318秒 ≈ 132 時間(週 3 日分)
After: 5 × [100 × 249 + 200 × 25]秒 ≈ 42 時間(週 1 日分)
削減: 約 90 時間/月 ≈ 週 2 日分の開発時間を回復
ポイント
- ボトルネック分析は CloudFormation ログの秒単位追跡 が鍵
- IAM 権限増やさず即座に効く修正が優先(実装容易、本番適用早い)
- リソースの 依存関係を見直す だけで大きな効果
おわり。