- 1 DevOps/CI/CD実践 Vol2 — Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting
- 1.1 1. なぜVol2か — Vol1からの架橋 + デプロイ対象別 CD の必要性
- 1.2 2. DevOps 深化マップ — Container CD / Package管理 / Serverless CD / Static Hosting
- 1.2.1 2-1. DevOps 深化マップ — 4本柱の位置付け
- 1.2.2 2-2. Container CD の選定軸
- 1.2.3 2-3. Package管理の選定軸
- 1.2.4 2-4. Serverless CD の選定軸
- 1.2.5 2-5. Static Hosting の選定軸
- 1.2.6 2-6. 4柱統合パイプラインの全体像
- 1.2.7 2-7. ep-box: 4本柱比較まとめ
- 1.2.8 2-8. Terraform 例 — SAM Pipeline クロスアカウント IAM Role
- 1.2.9 2-9. buildspec.yml 統合例 — CodeArtifact + Container CD の組み合わせ
- 1.3 3. Container CD 実践 ★山場1 — ECS Blue/Green × EKS GitOps × ECR
- 1.4 4. CodeArtifact 実践 — パッケージリポジトリ / 認証 / Dependency / Cross-Account
- 1.5 5. SAM Pipeline 実践 ★山場2 — Serverless CD / Bootstrap / Multi-Account Deploy
- 1.6 6. Amplify Hosting 実践 — Static/SPA CI/CD / Branch deploy / Preview deploy
- 1.7 7. アンチパターン→正解パターン変換演習 (5件)
- 1.7.1 演習1: ECS Blue/Green — Test traffic Listener Rule 設定漏れ (Terraform)
- 1.7.2 演習2: buildspec.yml — CodeArtifact login フェーズミス (YAML)
- 1.7.3 演習3: SAM template.yaml — Lambda Alias DeploymentPreference Hooks 順序ミス (YAML)
- 1.7.4 演習4: amplify.yml — SPA Rewrites 設定漏れで Direct URL 404 (YAML)
- 1.7.5 演習5: ECR Lifecycle Policy — untagged/tagged 誤削除 (JSON)
- 1.8 8. まとめ + Vol3予告 + 落とし穴10選 + 全10軸クロスリンク + Vol2完結宣言
DevOps/CI/CD実践 Vol2 — Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting

本記事は Vol1 (CodePipeline/CodeBuild/CodeDeploy/GitHub Actions OIDC) を読了した中堅エンジニアに向けた、Container CD・パッケージ管理・Serverless CD・静的サイトCI/CD の深化編です。Vol1の4本柱の上に、現代的なデプロイ対象別 (Container / Lambda / Static) の本番運用パターンを統合します。
前巻 (必読)
関連シリーズ (個別 deep-dive)
- ECS Fargate CI/CD Vol1-2 (Container CD の Fargate 限定 deep-dive)
- EKS+ArgoCD Production (Kubernetes GitOps の deep-dive)
- CodeArtifact + CodeGuru Production (CodeArtifact + 静的解析の deep-dive)
1. なぜVol2か — Vol1からの架橋 + デプロイ対象別 CD の必要性
1-1. Vol1の振り返り — 4本柱が解いた問題
Vol1 では CI/CD の基礎として以下の4本柱を習得しました。
| 本柱 | サービス | 解いた問題 |
|---|---|---|
| パイプライン オーケストレーション | CodePipeline | Source → Build → Test → Deploy の自動化フロー定義 |
| ビルド・テスト自動化 | CodeBuild | buildspec.yml による宣言型ビルド・コンテナ内隔離実行 |
| デプロイ自動化 | CodeDeploy | Blue/Green・In-Place・Canary の3戦略 + 自動ロールバック |
| GitHub Actions OIDC | GitHub Actions | 長命トークン排除・OIDC フェデレーションによる最小権限CD |
Vol1を読了したエンジニアは「汎用的な CI/CD ループ」を手に入れています。しかし現場では デプロイ対象が何か (Container イメージ / Lambda 関数 / 静的サイト) によって必要な追加インフラと運用パターンが大きく異なります。Vol1 の汎用 CD だけでは解決できない3種類のペインが存在します。
1-2. なぜ Vol1 の汎用 CD では不十分か — 3つのペイン
ペイン 1: Container CD のペイン
CodeDeploy は EC2/Lambda/ECS に対応していますが、Container 特有のイメージライフサイクル管理は別の仕組みが必要です。ECR (Elastic Container Registry) で image_tag_mutability = "IMMUTABLE" を設定しなければ latest タグの上書きによる本番事故が起き、ライフサイクルポリシーがなければ古いイメージが蓄積してストレージコストが膨張します。さらに EKS クラスタでは Argo CD / Flux による GitOps (宣言的同期) が事実上の標準ですが、CodeDeploy は EKS には対応していないため、全く別のデプロイ戦略が必要です。
ペイン 2: Serverless CD のペイン
Lambda 関数のデプロイでは SAM (Serverless Application Model) が最適解です。sam pipeline init で CI/CD 雛形を対話的に生成し、sam pipeline bootstrap でマルチアカウント対応 IAM Role + S3 バケットを自動プロビジョニングできます。Lambda Alias + Traffic Shifting (Canary 10% / Linear 10%毎10分 / All-at-once) による段階的ロールアウトは SAM テンプレートでのみ宣言的に管理でき、CodeDeploy の汎用 Deployment Group では Lambda Alias のライフサイクルが追いきれません。
ペイン 3: Package管理 と Static Hosting のペイン
チーム開発では社内パッケージの安全な配布が問題になります。npm / Maven / PyPI のパブリックレジストリに直接依存したままでは Dependency Confusion 攻撃リスクがあります。CodeArtifact でプライベートリポジトリを構築し、buildspec.yml の phases.pre_build で aws codeartifact login を実行して短命トークン (12時間有効) を取得する構成が必要です。フロントエンドの静的サイトは Amplify Hosting を使えば Branch deploy と PR ごとの Preview deploy が自動化されますが、CloudFront + S3 自前構築とのトレードオフを正しく理解しなければ誤選定が起きます。
1-3. Vol2 で得られる4つの成果
| # | 成果 | 習得後に解決できること |
|---|---|---|
| 1 | Container CD | ECR イメージ管理 + ECS Blue/Green + EKS GitOps の本番パターン実装 |
| 2 | Package管理 | CodeArtifact プライベートリポジトリ + buildspec.yml 統合による安全な依存解決 |
| 3 | Serverless CD | SAM Pipeline によるマルチアカウント Lambda デプロイ完全自動化 |
| 4 | Static Hosting | Amplify Hosting による SPA/SSG の Branch/Preview deploy + Custom Domain 設定 |
1-4. 既存シリーズとの住み分け
本 Vol2 は 概念整理 + 選定軸 + 最小 IaC 例 の提供に絞ります。詳細な deep-dive は以下の専門シリーズを参照してください。
| 既存シリーズ | 対象読者 | 本 Vol2 との関係 |
|---|---|---|
| ECS Fargate CI/CD Vol1-2 | Fargate 本番運用の詳細設定が必要な方 | §3 の ECS Blue/Green を補完 (ALB ターゲットグループ詳細・健全性チェック設定等) |
| EKS+ArgoCD Production | Kubernetes GitOps を完全実装したい方 | §3 の EKS GitOps を補完 (App-of-Apps / Sync wave / IRSA 統合の完全実装) |
| CodeArtifact + CodeGuru | パッケージ管理 + 静的解析を一体化したい方 | §4 の CodeArtifact を補完 (CodeGuru 統合・詳細ポリシー設定等) |
1-5. 本記事の構成 (第10軸シリーズ Vol2)
| § | テーマ | 行数目標 |
|---|---|---|
| §1 (本節) | Vol1架橋 + デプロイ対象別ペイン + 成果 | 150-180行 |
| §2 | DevOps深化マップ (4本柱位置付け + 選定軸) | 200-240行 |
| §3 ★山場1 | Container CD実践 (ECS Blue/Green × EKS GitOps × ECR) | 250-290行 |
| §4 | CodeArtifact実践 (パッケージリポジトリ / 認証 / Cross-Account) | 220-260行 |
| §5 ★山場2 | SAM Pipeline実践 (Serverless CD / Bootstrap / マルチアカウント) | 250-290行 |
| §6 | Amplify Hosting実践 (Branch/Preview deploy / Custom Domain) | 220-260行 |
| §7 | アンチパターン→正解パターン演習5件 | 200-250行 |
| §8 | まとめ + 落とし穴10選 + 全10軸クロスリンク | 100-140行 |
1-6. Terraform 例 — ECR リポジトリ (Container CD の起点)
Vol2 の Container CD を始める第一歩は ECR リポジトリの適切な設定です。以下は本番運用で必須となる設定を含む最小構成です。
resource "aws_ecr_repository" "app" {
name = "myapp"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
}
tags = {
Environment = "production"
ManagedBy= "terraform"
}
}
resource "aws_ecr_lifecycle_policy" "app" {
repository = aws_ecr_repository.app.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "untagged images を 7日後に削除"
selection = {
tagStatus= "untagged"
countType= "sinceImagePushed"
countUnit= "days"
countNumber = 7
}
action = { type = "expire" }
}
]
})
}
image_tag_mutability = "IMMUTABLE" が Container CD の必須設定です。latest タグの上書きを防ぎ、ロールバック時に旧バージョンイメージが消失する事故を根本から防止します。scan_on_push = true で ECR 拡張スキャンが有効になり、OS レベルとアプリケーション依存の両方の脆弱性を検出します。encryption_type = "KMS" はコンプライアンス要件対応としてカスタマーマネージドキーを指定する際のベースラインです。
1-7. 本 Vol2 の対象読者と前提知識
| 前提知識 | 推奨記事 | 重要度 |
|---|---|---|
| IAM ロールと OIDC フェデレーション | IAM Vol1 / Vol4 | ★★★ (GitHub Actions OIDC で必須) |
| CodePipeline / CodeBuild / CodeDeploy の基本 | DevOps Vol1 | ★★★ (必読) |
| ECS Fargate の基本的な運用 | ECS Fargate CI/CD Vol1 | ★★☆ (§3 で参照) |
| EKS クラスタ構成と IRSA | EKS Vol1 / EKS Vol3 | ★★☆ (§3 GitOps で参照) |
| Terraform の基礎文法 (HCL) | — | ★★☆ (IaC 例を読む場合) |
Vol1 未読の方: 先に DevOps Vol1 を読んでください。Vol2 の各節は Vol1 の CodePipeline / CodeBuild / CodeDeploy / GitHub Actions OIDC の知識を前提として書かれています。Vol1 未読のまま Vol2 を読むと、ビルドステージや承認ゲートの設定箇所が文脈なしに現れるため理解が困難になります。
§3・§5 だけ読みたい方: 各節の冒頭にある「このセクションで使う前提リソース」リストを確認し、必要な IaC を先に apply してから本文を読むと効率的です。
1-8. 全10軸 + DevOps Vol2 ナビ (22記事)
- IAM Vol1 — IAM ポリシー設計の基礎
- IAM Vol2 — マルチアカウント設計
- IAM Vol3 — 権限棚卸し自動化
- IAM Vol4 — STS × Cross-Account
- EKS Vol1 — クラスタ設計 / IRSA / ALB Ingress
- EKS Vol2 — Observability (FluentBit / ADOT)
- EKS Vol3 — GitOps (Argo CD)
- 復旧Vol1 — Backup × Cross-Region DR
- 復旧Vol2 — Chaos Engineering × FIS
- 復旧Vol3 — 自動化 Runbook
- 復旧Vol4 — マルチリージョン Active/Passive
- AI Vol1 — Bedrock Agents 基礎
- AI Vol2 — Knowledge Bases × RAG
- セキュリティVol1 — セキュリティ運用の基礎
- セキュリティVol2 — SOC統合運用
- コストVol1 — コスト最適化の基礎
- マルチアカウントVol1 — 統合運用基礎
- ObservabilityVol1 — 可観測性の基礎
- NetworkVol1 — VPC設計の基礎
- NetworkVol2 — ハイブリッド接続
- DevOps Vol1 — CodePipeline × CodeBuild × CodeDeploy × GitHub Actions OIDC
- DevOps Vol2 (本記事) — Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting
2. DevOps 深化マップ — Container CD / Package管理 / Serverless CD / Static Hosting
2-1. DevOps 深化マップ — 4本柱の位置付け
上図 (fig01: DevOps Vol2 全体図) が示すように、Vol2 では Vol1 の4本柱 (CodePipeline/CodeBuild/CodeDeploy/GitHub Actions) を基盤として、デプロイ対象別に特化した4つの深化柱を追加します。
| 深化柱 | 主サービス群 | 対象デプロイ物 | Vol1との関係 |
|---|---|---|---|
| Container CD | ECR + ECS CodeDeploy + EKS + Argo CD / Flux | コンテナイメージ | CodeDeploy ECS Platform を拡張 |
| Package管理 | CodeArtifact + buildspec.yml 統合 | npm / Maven / PyPI パッケージ | CodeBuild ビルドステップに統合 |
| Serverless CD | SAM Pipeline + SAM Bootstrap + Lambda Alias | Lambda 関数 + API Gateway | CodePipeline の Serverless 専用ステージ |
| Static Hosting | Amplify Hosting + CloudFront + S3 + OAC | React / Vue / Next.js / Astro | GitHub Actions の Static デプロイフロー |
Vol1 の4本柱が「CI/CD の骨格」なら、Vol2 の4深化柱は「デプロイ対象別の筋肉」です。骨格なしに筋肉はつかず、筋肉なしに実際の仕事はできません。両方を理解して初めて本番運用の全像が見えます。
2-2. Container CD の選定軸
ECS と EKS では CD 戦略が根本的に異なります。どちらを選ぶかは「コンテナオーケストレーターが ECS か Kubernetes か」で決まります。
| 選定軸 | ECS Fargate (CodeDeploy) | EKS (Argo CD / Flux) |
|---|---|---|
| デプロイ指定方法 | CodeDeploy Deployment Group (Console / Terraform) | GitOps Repo への Manifest Push |
| Blue/Green切替 | ALB Target Group 2セット切替 | Argo CD Rollout または Flagger |
| ロールバック | CloudWatch Alarm → CodeDeploy 自動 Rollback | Git Revert → Argo CD 自動同期 |
| カナリア | Test traffic % 設定 (ALB Listener Rule) | Argo Rollouts Canary Step |
| 採用基準 | ECS Fargate 中心・既存 CodeDeploy 資産がある場合 | Kubernetes 標準・マルチクラスタ・GitOps 中心 |
ECS Blue/Green の核心は Test Listener Rule の設定 です。ALB に2つのリスナー (本番ポート 443 / テストポート 8443) を設定し、CodeDeploy がデプロイ時に自動切替します。Test Listener Rule の設定漏れが最も多い失敗パターンです (§7 演習1)。
EKS GitOps の核心は Argo CD の Sync Wave です。Sync Wave を設定することで、データベースマイグレーション → アプリケーションデプロイ → 後処理ジョブ の順序保証が実現します。Sync Wave 設定漏れによる依存リソース順序事故が最多トラブルです (§8 落とし穴2)。
2-3. Package管理の選定軸
| 選定軸 | CodeArtifact | GitHub Packages | セルフホスト Nexus |
|---|---|---|---|
| AWS 統合 | ネイティブ (IAM / KMS / VPC Endpoint) | GitHub Actions 統合 | 手動 IAM 設定 |
| 対応フォーマット | npm / Maven / PyPI / NuGet / Swift / generic | npm / Maven / NuGet / Docker / RubyGems | 全フォーマット対応 |
| 認証方式 | aws codeartifact get-authorization-token (12h TTL) | GitHub PAT / OIDC | API Key / LDAP |
| Cross-Account | Resource Policy / Domain Policy でネイティブ対応 | Organization Package | ネットワーク設定依存 |
| コスト | $0.05/GB ストレージ + $0.09/GB 転送 | GitHub Enterprise で利用可 | サーバー運用コスト |
CodeArtifact の認証トークン有効期限は 12時間 です。長時間 CI (夜間バッチ等) では phases.pre_build でのトークン再取得ステップが必須です (§7 演習2)。
2-4. Serverless CD の選定軸
| 選定軸 | SAM Pipeline | CDK Pipelines | Serverless Framework |
|---|---|---|---|
| 標準化度 | AWS 公式 (CloudFormation ネイティブ) | AWS 公式 (L3 Construct) | サードパーティ |
| Bootstrap | sam pipeline bootstrap (IAM Role + S3 自動作成) | cdk bootstrap | 手動 IAM 設定 |
| Traffic Shifting | Lambda Alias + DeploymentPreference (Canary / Linear) | CodeDeploy 統合 | Plugin 依存 |
| マルチアカウント対応 | Pipeline Bootstrap で各アカウントの Role 作成 | CDK Bootstrap + Trusted Accounts | 手動設定 |
| 採用基準 | Lambda 中心・CloudFormation 標準に従いたい場合 | CDK 全面採用している場合 | 既存 FW 資産がある場合 |
SAM Bootstrap の 役割 は、Staging / Prod 各アカウントに samCLIRole / cfnExecutionRole / pipelineArtifactsBucket を作成し、パイプラインアカウントからのクロスアカウントデプロイを可能にすることです。SAM Bootstrap を重複実行すると既存 IAM Role との命名衝突エラーが発生します (§8 落とし穴5)。
2-5. Static Hosting の選定軸
| 選定軸 | Amplify Hosting | CloudFront + S3 自前構築 |
|---|---|---|
| セットアップ | Console / CLI で数分 | Terraform ~150行 |
| Branch deploy | ビルトイン (自動) | 手動または Lambda@Edge が必要 |
| Preview deploy | PR ごとに自動 URL 発行 | 手動 CI/CD 実装が必要 |
| Custom Domain | Console または Terraform (自動 ACM 発行) | 手動 ACM + Route 53 + CloudFront Origins |
| Cache制御 | Amplify が自動管理 (細粒度制御は制限あり) | CloudFront Behavior/TTL を完全制御可能 |
| 採用基準 | 開発速度重視・フロントエンド単体でデプロイ | CDN 細粒度制御・複雑な Routing ルール必要 |
Amplify Hosting の SPA routing で最も多いトラブルが Rewrites/Redirects の設定漏れ です。/* → /index.html への Rewrite が未設定だと、Direct URL アクセス (/about 等) で 403/404 が発生します (§7 演習4)。
2-6. 4柱統合パイプラインの全体像
Vol2 の最終形は、Container / Lambda / Static の3デプロイ対象を1つのリポジトリから管理するモノレポ + マルチパイプライン構成です。
[GitHub Repo: monorepo]
├── services/
│├── api/→ CodePipeline (Container CD: ECS Blue/Green)
│├── functions/→ CodePipeline (Serverless CD: SAM Pipeline)
│└── frontend/ → Amplify Hosting (Static CD: Branch deploy)
└── packages/
└── shared-lib/ → CodeArtifact (Package管理: npm publish)
各パイプラインの連携ポイント:
shared-libの変更 → CodeArtifact に publish →api/functionsの buildspec.yml がcodeartifact loginで最新版取得apiの変更 → CodePipeline 起動 → CodeBuild (ビルド + ECR push) → CodeDeploy (ECS Blue/Green)functionsの変更 → CodePipeline 起動 → SAM build → SAM deploy (Lambda Alias Traffic Shifting)frontendの変更 → Amplify Hosting が自動検知 → Branch build → Preview deploy (PR) / Production deploy (main)
2-7. ep-box: 4本柱比較まとめ
| 柱 | 対象 | キーサービス | Vol1との差分 |
|—|——|————|————|
| Container CD | コンテナイメージ | ECR / ECS CodeDeploy / EKS+Argo CD | ECR ライフサイクル管理 + GitOps が追加 |
| Package管理 | ライブラリ/成果物 | CodeArtifact | buildspec.yml への codeartifact login 統合 |
| Serverless CD | Lambda / API GW | SAM Pipeline / SAM Bootstrap | Alias Traffic Shifting が追加 |
| Static Hosting | SPA / SSG | Amplify Hosting / CloudFront+S3 | Branch / Preview deploy が追加 |
選定早見き: Container → ECR+ECS (Fargate) または EKS (Kubernetes) / Serverless → SAM (AWS標準) または CDK Pipelines (CDK採用時) / Static → Amplify (速度重視) または CloudFront+S3 (細粒度制御)
2-8. Terraform 例 — SAM Pipeline クロスアカウント IAM Role
SAM Pipeline のマルチアカウント構成で sam pipeline bootstrap が作成する IAM Role を Terraform で定義する例です。
resource "aws_iam_role" "sam_pipeline_execution" {
name = "samCLIRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${var.pipeline_account_id}:root"
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"sts:ExternalId" = var.pipeline_external_id
}
}
}
]
})
tags = {
ManagedBy= "terraform"
Environment = var.environment
}
}
resource "aws_iam_role_policy" "sam_pipeline_execution" {
name = "samCLIPipelinePolicy"
role = aws_iam_role.sam_pipeline_execution.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack",
"cloudformation:DescribeStacks",
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:CreateAlias",
"lambda:UpdateAlias",
"s3:GetObject",
"s3:PutObject"
]
Resource = "*"
}
]
})
}
sts:ExternalId 条件はクロスアカウント AssumeRole の混乱代理問題 (Confused Deputy) 対策として必須です。パイプラインアカウント ID と組み合わせることで、意図しない第三者からの AssumeRole を防止します。
2-9. buildspec.yml 統合例 — CodeArtifact + Container CD の組み合わせ
以下は CodeArtifact (npm) + ECR push を組み合わせた buildspec.yml の例です。Vol2 の Package管理 と Container CD を1つの CodeBuild ジョブで実現します。
version: 0.2
phases:
install:
runtime-versions:
nodejs: 20
commands:
- CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
--domain mycompany --domain-owner $AWS_ACCOUNT_ID \
--query authorizationToken --output text)
- npm config set registry https://mycompany-${AWS_ACCOUNT_ID}.d.codeartifact.${AWS_REGION}.amazonaws.com/npm/myrepo/
- npm config set //mycompany-${AWS_ACCOUNT_ID}.d.codeartifact.${AWS_REGION}.amazonaws.com/npm/myrepo/:_authToken $CODEARTIFACT_TOKEN
- npm install
pre_build:
commands:
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
- npm run lint
- npm run test
build:
commands:
- docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$CODEBUILD_BUILD_NUMBER .
- docker push $ECR_REGISTRY/$ECR_REPOSITORY:$CODEBUILD_BUILD_NUMBER
post_build:
commands:
- printf '[{"name":"app","imageUri":"%s:%s"}]' $ECR_REGISTRY/$ECR_REPOSITORY $CODEBUILD_BUILD_NUMBER > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
phases.install で CodeArtifact トークンを取得し npm config に設定する点が鍵です。phases.pre_build 以降はすでに認証済みのレジストリを使うため、依存解決が失敗しません。imagedefinitions.json は CodeDeploy が ECS Blue/Green のデプロイ対象イメージを特定するために使うアーティファクトです。
3. Container CD 実践 ★山場1 — ECS Blue/Green × EKS GitOps × ECR
3-1. Container CD の全体像 — ECS vs EKS 選定軸
Container ワークロードの CD 戦略は、オーケストレーション層 (ECS か EKS か) によって大きく2方向に分かれる。ECS では AWS マネージドの CodeDeploy ECS Blue/Green が中心となり、EKS では Git リポジトリを唯一の信頼源とする GitOps (Argo CD / Flux) が標準パターンとなる。いずれも「ゼロダウンタイムでのコンテナ入れ替え」を実現するが、制御層の設計思想が根本的に異なる。
| 比較軸 | ECS Blue/Green (CodeDeploy) | EKS GitOps (Argo CD / Flux) |
|---|---|---|
| CD エンジン | AWS CodeDeploy (ECS Compute Platform) | Argo CD / Flux (クラスタ内エージェント) |
| デプロイ方式 | Push 型 (CodePipeline からトリガー) | Pull 型 (Git 変更を Argo CD が検知) |
| 切り戻し | CloudWatch Alarm 自動切り戻し | Git Revert / Argo CD Sync undo |
| 状態管理 | CodeDeploy コンソール / CloudWatch | Argo CD UI / kubectl |
| Terraform 統合 | aws_codedeploy_* リソース | argocd_application または kubectl manifest |
| 向いている構成 | ECS Fargate 単一サービス / 少数マイクロサービス | Kubernetes Multi-Service / マルチクラスタ |
ECS を使う場合は §3-2 の Blue/Green を、Kubernetes を使う場合は §3-3 の GitOps を参照されたい。ECR は ECS/EKS 双方で使うコンテナレジストリとして §3-4 で扱う。

3-2. ECS Blue/Green Deploy (CodeDeploy ECS Compute Platform)
ECS Blue/Green デプロイは、ALB の Target Group を 2 セット (Blue: 既存本番タスク / Green: 新版タスク) 用意し、トラフィックを段階的に切り替えることでゼロダウンタイムを実現する。AWS CodeDeploy の ECS Compute Platform がこの切替プロセスをオーケストレーションする。
Blue/Green 切替の仕組み
ALB Listener (Port 443)
├── Production Listener Rule → Blue Target Group (既存タスク: 本番トラフィック受信)
└── Test Listener Rule → Green Target Group (新タスク: 検証トラフィック受信)
- CodeDeploy が新しいタスク定義で Green Target Group にタスクを起動
- Test Listener (Port 8080) に一部トラフィックを流し、アプリケーションの動作確認
- 確認 OK → Production Listener を Green に切替 (Blue の重みを 0 に)
- Blue タスクは指定した Termination wait time 後に削除
ALB Listener Rule の重み付け (Canary デプロイ)
段階的切替では ALB Weighted Target Group を使って本番トラフィックを徐々に移行できる。Blue:90 / Green:10 → Blue:50 / Green:50 → Blue:0 / Green:100 のように重みを段階的に変化させる Canary デプロイにより、新版の品質を本番で確認しながらリスクを最小化できる。
Auto 切り戻し (CloudWatch Alarm 閾値)
CodeDeploy のデプロイグループに CloudWatch Alarm を設定すると、デプロイ中にアラームが発火した時点で自動的に Blue へ切り戻す。aws_cloudwatch_metric_alarm で HTTP 5xx エラー率が閾値 (例: 5%) を超えたら自動切り戻しする設定が典型パターンだ。
Terraform 例: ECS Blue/Green
resource "aws_codedeploy_app" "ecs_app" {
name = "my-ecs-app"
compute_platform = "ECS"
}
resource "aws_codedeploy_deployment_group" "ecs_dg" {
app_name= aws_codedeploy_app.ecs_app.name
deployment_group_name = "my-ecs-deployment-group"
service_role_arn = aws_iam_role.codedeploy.arn
deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes"
auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
}
alarm_configuration {
alarms = [aws_cloudwatch_metric_alarm.http5xx.name]
enabled = true
}
blue_green_deployment_config {
deployment_ready_option {
action_on_timeout = "CONTINUE_DEPLOYMENT"
wait_time_in_minutes = 5
}
terminate_blue_instances_on_deployment_success {
action= "TERMINATE"
termination_wait_time_in_minutes = 10
}
}
deployment_style {
deployment_option = "WITH_TRAFFIC_CONTROL"
deployment_type= "BLUE_GREEN"
}
ecs_service {
cluster_name = aws_ecs_cluster.main.name
service_name = aws_ecs_service.main.name
}
load_balancer_info {
target_group_pair_info {
prod_traffic_route { listener_arns = [aws_lb_listener.prod.arn] }
test_traffic_route { listener_arns = [aws_lb_listener.test.arn] }
target_group { name = aws_lb_target_group.blue.name }
target_group { name = aws_lb_target_group.green.name }
}
}
}
3-3. EKS GitOps (Argo CD / Flux)
EKS 環境では GitOps が実質的な標準デプロイパターンとなっている。Git リポジトリが唯一の信頼源 (Source of Truth) となり、クラスタ内の Argo CD / Flux エージェントが継続的に Git と同期する Pull 型アーキテクチャだ。
Container CD パイプライン実行フロー
sequenceDiagram
participant Dev as 開発者
participant GH as GitHub
participant CB as CodeBuild
participant ECR as ECR
participant ArgoCD as Argo CD
participant EKS as EKS Cluster
Dev->>GH: git push (アプリコード)
GH->>CB: Webhook → Build trigger
CB->>ECR: docker build → docker push (タグ: sha-abc1234)
CB->>GH: GitOps repo の image tag を更新 (PR merge)
GH-->>ArgoCD: (Pull) image tag 変更を検知
ArgoCD->>EKS: kubectl apply (新イメージ Deployment)
EKS-->>ArgoCD: Sync OK / Health OK
ArgoCD-->>Dev: デプロイ完了通知
Cluster Bootstrap (Argo CD)
Argo CD を EKS クラスタへ導入する標準手順は Helm Chart 経由だ。argocd 名前空間に Argo CD コンポーネントをデプロイし、最初の Application (App-of-Apps) を手動登録することでブートストラップが完了する。
GitOps リポジトリ構造
GitOps ではアプリケーションコードと Kubernetes manifest を分離するリポジトリ設計が鉄則だ。
gitops-repo/
apps/
my-app/
base/ # 共通 manifest (Deployment / Service)
overlays/
dev/# dev 差分 (replica: 1 / namespace: dev)
staging/ # staging 差分
prod/ # prod 差分 (replica: 3 / PodDisruptionBudget)
clusters/
dev/ # App-of-Apps (dev クラスタ向け)
prod/# App-of-Apps (prod クラスタ向け)
Sync Wave / Pre-sync / Post-sync Hook
依存関係のあるリソース (CRD → CR / ConfigMap → Deployment) は Sync wave で順序制御する。argocd.argoproj.io/sync-wave: "0" で早期適用、"5" で後から適用というアノテーションで制御する。Pre-sync hook は DB マイグレーション、Post-sync hook は Smoke test の実行に活用されるパターンが多い。
App-of-Apps パターン
Argo CD の Application リソース自体を Argo CD で管理する再帰パターンだ。clusters/prod/ に置いた App-of-Apps Application が apps/ 以下の全アプリを一括管理し、新サービス追加が Git コミット1件で完結する。
Terraform 例: argocd_application (HCL)
resource "argocd_application" "my_app" {
metadata {
name= "my-app"
namespace = "argocd"
}
spec {
project = "default"
source {
repo_url = "https://github.com/my-org/gitops-repo.git"
path= "apps/my-app/overlays/prod"
target_revision = "main"
}
destination {
server = "https://kubernetes.default.svc"
namespace = "my-app"
}
sync_policy {
automated {
prune = true
self_heal = true
}
sync_options = ["CreateNamespace=true"]
}
}
}
3-4. ECR (Elastic Container Registry) 実践
ECR はコンテナイメージの保管・脆弱性スキャン・レプリケーションを担う AWS マネージドレジストリだ。ECS/EKS を問わず使われる共通インフラとなるため、正しい設定が Container CD 全体の安全性に直結する。
Image Tag Immutability
imageTagMutability: IMMUTABLE を設定すると、同一タグへの上書き push が禁止される。latest タグを使い回して「どのイメージがデプロイ中か分からない」状態を防ぐためにも、本番環境では必須の設定だ。Git commit SHA をタグとして使う運用 (sha-a1b2c3d) と組み合わせると、デプロイ履歴の追跡と確実な切り戻しが可能になる。
Vulnerability Scanning (Enhanced Scanning / Amazon Inspector V2)
ECR Enhanced Scanning は Amazon Inspector V2 と統合し、OS パッケージとアプリケーション依存ライブラリの CVE をスキャンする。基本スキャン (SCAN_ON_PUSH のみ) と異なり、新しい CVE が公開された際に既存イメージを自動的に再スキャンする継続評価機能を持つ。
Lifecycle Policy (untagged image 削除)
ECR ライフサイクルポリシーで古いイメージを自動削除する。CI が失敗した際の中間成果物 (untagged image) はそのまま蓄積するとストレージコストが増大するため、7日以上経過した untagged image を削除するルールが基本設定となる。
Cross-Region Replication
Multi-Region デプロイ環境では ECR Replication Rule を設定し、Primary Region のイメージを Secondary Region に自動コピーする。各リージョンの ECS/EKS がローカル ECR からイメージを pull することで、クロスリージョン転送コストと pull レイテンシーを削減できる。
Terraform 例: ECR
resource "aws_ecr_repository" "app" {
name = "my-app"
image_tag_mutability = "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
}
resource "aws_ecr_lifecycle_policy" "app" {
repository = aws_ecr_repository.app.name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Expire untagged images older than 7 days"
selection = {
tagStatus= "untagged"
countType= "sinceImagePushed"
countUnit= "days"
countNumber = 7
}
action = { type = "expire" }
},
{
rulePriority = 2
description = "Keep only the last 30 SHA-tagged images"
selection = {
tagStatus = "tagged"
tagPrefixList = ["sha-"]
countType = "imageCountMoreThan"
countNumber= 30
}
action = { type = "expire" }
}
]
})
}
resource "aws_ecr_replication_configuration" "main" {
replication_configuration {
rule {
destination {
region= "ap-southeast-1"
registry_id = data.aws_caller_identity.current.account_id
}
}
}
}
ECR の imageTagMutability を MUTABLE (デフォルト) のまま運用し、latest タグで push → 切り戻し時に古いイメージが存在しないという事故が多発する。latest は常に最新イメージを指すため、新版を push した時点で旧版 latest は上書きされ、切り戻し先が消える。
- 発生条件:
imageTagMutability: MUTABLE+latestタグ運用 + 切り戻し操作 - 対策:
imageTagMutability: IMMUTABLEに変更し、Git commit SHA をタグとして使う (sha-a1b2c3d) - GitOps での切り戻し: GitOps リポジトリで image tag を旧 SHA に戻す変更をコミットし、Argo CD が自動 Sync することで旧版へ確実に戻せる
- EKS本番運用 Vol3: GitOps × ArgoCD 完全ガイド — App-of-Apps / ApplicationSet / Sync戦略 の完全実装ガイド
- EKS本番運用 Vol1: クラスタ設計 × IRSA × ALB Ingress — EKS クラスタ設計・IRSA・ALB Ingress の基礎固め
本 §3 は Container CD の概念整理・選定軸・実装例に絞った解説です。EKS GitOps の完全実装 (ApplicationSet・マルチクラスタ・Sync wave 詳細) は上記 EKS deep-dive 記事を参照してください。
4. CodeArtifact 実践 — パッケージリポジトリ / 認証 / Dependency / Cross-Account
4-1. CodeArtifact の位置付け — Maven Central / npm / PyPI のプロキシ + 私設リポジトリ
CodeArtifact はフルマネージドのパッケージリポジトリサービス。パブリックレジストリ (Maven Central / npm / PyPI / NuGet) へのプロキシと、社内限定の私設リポジトリの両方を提供する。
| 用途 | 従来の課題 | CodeArtifact の解決策 |
|---|---|---|
| 外部パッケージのキャッシュ | 毎回 Maven Central 等から取得 → CI が遅い・ネット障害で失敗 | upstream キャッシュで高速取得・オフラインビルド可 |
| 社内ライブラリ共有 | S3 や Nexus 等を自前管理 | フルマネージドで運用コスト削減 |
| サプライチェーン攻撃対策 | 直接パブリックレジストリを参照 | 承認済みパッケージのみ upstream に設定 |
パブリックレジストリとの住み分け:
開発者/CodeBuild
↓ npm install / mvn package
CodeArtifact Repository (Internal)
↓ upstream chain
Maven Central / npm Registry / PyPI
4-2. Domain / Repository 階層構造
CodeArtifact は Domain → Repository の 2 層構造で管理する。
Domain: mycompany (AWS Account: 123456789012)
├── Repository: internal-maven (社内 Java ライブラリ)
│└── upstream: maven-central(パブリックプロキシ)
├── Repository: internal-npm (社内 Node.js ライブラリ)
│└── upstream: npmjs(npm registry プロキシ)
└── Repository: shared-pypi (Python ライブラリ)
└── upstream: pypi (PyPI プロキシ)
Domain の役割: 複数 Repository をグループ化し、Cross-Account 共有の単位となる。KMS 暗号化は Domain 単位で設定。
resource "aws_codeartifact_domain" "main" {
domain= "mycompany"
encryption_key = aws_kms_key.codeartifact.arn
tags = {
Name = "mycompany-artifact-domain"
}
}
resource "aws_codeartifact_repository" "internal_npm" {
repository = "internal-npm"
domain = aws_codeartifact_domain.main.domain
upstream {
repository_name = aws_codeartifact_repository.npmjs_proxy.repository
}
tags = {
Name = "internal-npm"
}
}
resource "aws_codeartifact_repository" "npmjs_proxy" {
repository = "npmjs"
domain = aws_codeartifact_domain.main.domain
external_connections {
external_connection_name = "public:npmjs"
}
}
4-3. 認証フロー — 短命トークンと IAM 統合
CodeArtifact へのアクセスには短命の認証トークン (有効期限: デフォルト 12 時間、最大 12 時間) が必要。aws codeartifact get-authorization-token で取得し、npm / mvn / pip の設定ファイルに注入する。
npm 認証例:
# CodeBuild / CI での認証
CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
--domain mycompany \
--domain-owner 123456789012 \
--query authorizationToken \
--output text)
npm config set registry https://mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/npm/internal-npm/
npm config set //mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/npm/internal-npm/:_authToken $CODEARTIFACT_AUTH_TOKEN
buildspec.yml 統合例:
version: 0.2
phases:
pre_build:
commands:
- CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token
--domain mycompany --domain-owner $AWS_ACCOUNT_ID
--query authorizationToken --output text)
- aws codeartifact login --tool npm --domain mycompany
--domain-owner $AWS_ACCOUNT_ID --repository internal-npm
build:
commands:
- npm ci
- npm run build
- npm publish --registry https://mycompany-$AWS_ACCOUNT_ID.d.codeartifact.ap-northeast-1.amazonaws.com/npm/internal-npm/
IAM Role 設計:
resource "aws_iam_role_policy" "codebuild_codeartifact" {
name = "codeartifact-access"
role = aws_iam_role.codebuild.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"codeartifact:GetAuthorizationToken",
"codeartifact:ReadFromRepository",
"codeartifact:PublishPackageVersion",
"sts:GetServiceBearerToken"
]
Resource = "*"
}
]
})
}
4-4. Cross-Account 共有 — Resource Policy / Domain Policy
複数 AWS Account で同一 CodeArtifact Domain / Repository を共有する場合は Resource Policy を設定する。
resource "aws_codeartifact_domain_permissions_policy" "cross_account" {
domain = aws_codeartifact_domain.main.domain
domain_owner = data.aws_caller_identity.current.account_id
policy_document = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { AWS = "arn:aws:iam::987654321098:root" }
Action = [
"codeartifact:GetAuthorizationToken",
"codeartifact:DescribeDomain",
"sts:GetServiceBearerToken"
]
Resource = "*"
}
]
})
}
resource "aws_codeartifact_repository_permissions_policy" "cross_account" {
repository= aws_codeartifact_repository.internal_npm.repository
domain = aws_codeartifact_domain.main.domain
domain_owner = data.aws_caller_identity.current.account_id
policy_document = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { AWS = "arn:aws:iam::987654321098:root" }
Action = ["codeartifact:ReadFromRepository", "codeartifact:DescribeRepository"]
Resource = "*"
}
]
})
}
4-5. Dependency 解決 — upstream repository chain
CodeArtifact の upstream chain により、パッケージ検索順序を制御できる。
クライアント → internal-npm (CodeArtifact)
├── 内部パッケージ → ヒット → 返す
└── 内部になし → npmjs (upstream = npm registry プロキシ)
└── ヒット → internal-npm にキャッシュ → 返す
重要ポイント:
– upstream でキャッシュされたパッケージはその後の取得が高速化される
– allow / block 設定で外部パッケージの流入を制限できる (サプライチェーン管理)
– 複数 upstream を指定した場合は登録順に検索される
Maven (mvn) 認証と publish 例:
# .m2/settings.xml の自動更新
aws codeartifact login --tool mvn \
--domain mycompany \
--domain-owner $AWS_ACCOUNT_ID \
--repository internal-maven
# パッケージのデプロイ
mvn deploy -DaltDeploymentRepository=internal-maven::default::https://mycompany-$AWS_ACCOUNT_ID.d.codeartifact.ap-northeast-1.amazonaws.com/maven/internal-maven/
pip (Python) 認証例:
# pip の設定
aws codeartifact login --tool pip \
--domain mycompany \
--domain-owner $AWS_ACCOUNT_ID \
--repository shared-pypi
# インストール確認
pip install boto3 # shared-pypi 経由で取得・キャッシュ
CodeArtifact の認証トークンはデフォルト 12 時間で失効します。通常の CI ビルドでは問題ありませんが、長時間のインテグレーションテストやバッチビルドでは途中で失効してパッケージ取得が失敗します。
対策:
- 短縮トークン + 再取得: buildspec の各 phase 開始時に
get-authorization-tokenを再実行し、新しいトークンを取得する - CodeBuild Service Role 活用:
aws codeartifact loginコマンドはデフォルトで実行ロールの認証情報を使用するため、Service Role に適切な権限を付与すれば再ログイン不要 - npm credential helper:
@aws-sdk/codeartifact-npm-loginを使うと npm install 時に自動的にトークンを更新できる
5. SAM Pipeline 実践 ★山場2 — Serverless CD / Bootstrap / Multi-Account Deploy
5-1. SAM の位置付け — CloudFormation 上の Serverless 抽象化
AWS SAM (Serverless Application Model) は CloudFormation を基盤とした Serverless 専用 IaC ツール。AWS::Serverless::Function 等の簡略化されたリソース型で Lambda + API Gateway + DynamoDB 等を数十行で定義できる。
| 比較軸 | SAM | Terraform |
|---|---|---|
| 対象 | Serverless (Lambda/API GW/DynamoDB) | 汎用 (あらゆる AWS リソース) |
| デプロイ方式 | sam deploy (CloudFormation Stack) | terraform apply (State 管理) |
| ローカル実行 | sam local invoke でローカルテスト可 | なし (LocalStack 等が必要) |
| CI/CD 雛形 | sam pipeline init で自動生成 | 手動構築 |
| 選定目安 | Lambda 中心のサービス / 迅速な Serverless 開発 | 複数リソース統合 / 既存 Terraform 資産活用 |
SAM template.yaml 例 (Node.js):
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: nodejs20.x
Timeout: 30
Environment:
Variables:
TABLE_NAME: !Ref ItemsTable
Resources:
GetItemFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/get-item.handler
Policies:
- DynamoDBReadPolicy:
TableName: !Ref ItemsTable
Events:
GetItem:
Type: Api
Properties:
Path: /items/{id}
Method: get
ItemsTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: String
Outputs:
ApiEndpoint:
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod"
5-2. sam pipeline init — CI/CD 雛形の自動生成
sam pipeline init は対話形式で CI/CD パイプラインの設定ファイルを生成するコマンド。
sam pipeline init
# 対話的な設定
# CI/CD プロバイダー選択:
#1. AWS CodePipeline
#2. GitHub Actions
#3. Jenkins
#4. GitLab CI/CD
# 生成されるファイル:
# .aws-sam/pipeline/pipelineconfig.toml
# codepipeline.yaml (または .github/workflows/pipeline.yaml)
# assume-role.sh
GitHub Actions 生成例 (pipeline.yaml 抜粋):
name: SAM Pipeline
on:
push:
branches: [main, develop]
jobs:
build-and-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/setup-sam@v2
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-sam-deploy
aws-region: ap-northeast-1
- run: sam build
- run: sam package --s3-bucket ${{ secrets.PIPELINE_ARTIFACTS_BUCKET }} --output-template-file packaged.yaml
- uses: actions/upload-artifact@v4
with:
name: packaged-template
path: packaged.yaml
deploy-dev:
needs: build-and-package
runs-on: ubuntu-latest
environment: dev
steps:
- uses: actions/download-artifact@v4
with:
name: packaged-template
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.DEV_PIPELINE_EXECUTION_ROLE }}
aws-region: ap-northeast-1
- run: |
sam deploy --template-file packaged.yaml \
--stack-name my-app-dev \
--capabilities CAPABILITY_IAM \
--no-confirm-changeset \
--no-fail-on-empty-changeset
5-3. sam pipeline bootstrap — Multi-Account 環境準備
sam pipeline bootstrap は各環境 (dev / test / prod) に必要な AWS リソースを自動作成する。
# dev 環境のブートストラップ
sam pipeline bootstrap \
--stage dev \
--region ap-northeast-1 \
--pipeline-user arn:aws:iam::111111111111:user/github-actions-user \
--pipeline-execution-role arn:aws:iam::222222222222:role/dev-pipeline-execution-role \
--cloudformation-execution-role arn:aws:iam::222222222222:role/dev-cfn-execution-role \
--artifacts-bucket my-pipeline-artifacts-dev \
--image-repository 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-dev
# prod 環境のブートストラップ
sam pipeline bootstrap \
--stage prod \
--region ap-northeast-1 \
--pipeline-user arn:aws:iam::111111111111:user/github-actions-user \
--pipeline-execution-role arn:aws:iam::333333333333:role/prod-pipeline-execution-role \
--cloudformation-execution-role arn:aws:iam::333333333333:role/prod-cfn-execution-role \
--artifacts-bucket my-pipeline-artifacts-prod \
--image-repository 333333333333.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-prod
bootstrap が作成するリソース:
– IAM Role (PipelineExecutionRole): GitHub Actions / CodeBuild から AssumeRole されるロール
– IAM Role (CloudFormationExecutionRole): SAM が CloudFormation Stack を操作するロール
– S3 Bucket: ビルドアーティファクト保存
– ECR Repository: コンテナイメージ (Container-based Lambda 使用時)
5-4. Deploy Stages — 3 段階承認ゲート
dev → test → prod の 3 段階デプロイで品質ゲートを設ける。

sequenceDiagram
participant GH as GitHub Actions
participant DevAcc as Dev Account (222...)
participant TestAcc as Test Account (444...)
participant ProdAcc as Prod Account (333...)
GH->>GH: sam build + sam package
GH->>DevAcc: AssumeRole (PipelineExecutionRole-dev)
DevAcc->>DevAcc: sam deploy → Stack: my-app-dev
DevAcc-->>GH: Deploy complete (dev)
GH->>TestAcc: AssumeRole (PipelineExecutionRole-test)
TestAcc->>TestAcc: sam deploy → Stack: my-app-test
TestAcc-->>GH: Deploy complete (test)
Note over GH: Manual Approval Gate (GitHub Environment protection)
GH->>ProdAcc: AssumeRole (PipelineExecutionRole-prod)
ProdAcc->>ProdAcc: sam deploy --deployment-method trafficshifting
ProdAcc-->>GH: Deploy complete (prod / Canary 10%)
5-5. Lambda Alias Traffic Shifting — Canary / Linear / All-at-once
SAM は DeploymentPreference で Lambda Alias のトラフィック移行戦略を指定できる。
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/index.handler
Runtime: nodejs20.x
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes # 10% → 5分後 → 100%
Alarms:
- !Ref ApiErrorAlarm
Hooks:
PreTraffic: !Ref PreTrafficHook
PostTraffic: !Ref PostTrafficHook
PreTrafficHook:
Type: AWS::Serverless::Function
Properties:
Handler: src/hooks/pre-traffic.handler
Runtime: nodejs20.x
Policies:
- Version: "2012-10-17"
Statement:
- Effect: Allow
Action: codedeploy:PutLifecycleEventHookExecutionStatus
Resource: "*"
ApiErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: api-function-errors
MetricName: Errors
Namespace: AWS/Lambda
Statistic: Sum
Period: 60
Threshold: 5
ComparisonOperator: GreaterThanThreshold
EvaluationPeriods: 1
Dimensions:
- Name: FunctionName
Value: !Ref ApiFunction
Traffic Shifting 戦略一覧:
| 設定値 | 移行パターン | 推奨ユースケース |
|---|---|---|
Canary10Percent5Minutes | 10% → 5分後 → 100% | 一般的な本番 Lambda |
Canary10Percent15Minutes | 10% → 15分後 → 100% | 長時間テストが必要な場合 |
Linear10PercentEvery1Minute | 1分ごとに 10% 増 (10分で完了) | 緩やかな移行が必要な場合 |
AllAtOnce | 即時 100% | テスト環境 / 低リスク関数 |
5-6. samconfig.toml — 環境別パラメータ管理
version = 0.1
[default.global.parameters]
stack_name = "my-app"
region = "ap-northeast-1"
confirm_changeset = false
[dev.deploy.parameters]
stack_name = "my-app-dev"
s3_bucket = "my-pipeline-artifacts-dev"
image_repository = "222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-dev"
role_arn = "arn:aws:iam::222222222222:role/dev-cfn-execution-role"
parameter_overrides = "Environment=dev LogLevel=DEBUG"
[prod.deploy.parameters]
stack_name = "my-app-prod"
s3_bucket = "my-pipeline-artifacts-prod"
image_repository = "333333333333.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-prod"
role_arn = "arn:aws:iam::333333333333:role/prod-cfn-execution-role"
parameter_overrides = "Environment=prod LogLevel=INFO"
デプロイ実行:
sam deploy --config-env dev# dev 環境
sam deploy --config-env prod # prod 環境
既存の dev/prod 環境に対して誤って sam pipeline bootstrap を再実行すると、既存の IAM Role や S3 Bucket が上書き・再作成されて権限設定が失われる事故が発生します。
よくある発生シナリオ:
- 新しい CI/CD プロバイダーへの移行時: GitHub Actions → CodePipeline に変更する際に既存環境に再 bootstrap → 既存 Role の Trust Policy が上書きされて旧 CI が認証不可になる
- チームメンバーが誤ってコマンド実行: ドキュメント通りにコマンドを実行したつもりが既存 prod 環境を指定してしまう
対策:
- bootstrap 前に既存リソースを確認:
aws cloudformation describe-stacks --stack-name aws-sam-cli-managed-dev-pipeline-resourcesで既存 Stack を確認 - 環境変数で誤操作防止:
samconfig.tomlのrole_arnに既存ロール ARN を明示し、bootstrap コマンドの実行を制限する - 本番環境の bootstrap は手順書化: prod bootstrap は Pull Request + レビューを経てから実行するワークフローを整備する
6. Amplify Hosting 実践 — Static/SPA CI/CD / Branch deploy / Preview deploy
6-1. Amplify Hosting の位置付け
AWS Amplify Hosting は Vercel / Netlify に相当する AWS ネイティブのフルマネージド静的サイト・SPA ホスティングサービス。フロントエンドのビルド・デプロイ・CDN 配信・カスタムドメイン管理を単一サービスで完結させる。GitHub / GitLab / Bitbucket リポジトリと直接連携し、push をトリガーに自動ビルド・デプロイが走る。
対応フレームワークと SSR サポート:
| フレームワーク | ビルドプリセット | SSR 対応 |
|---|---|---|
| React (CRA / Vite) | 自動検出 | × (CSR のみ) |
| Vue 3 / Vite | 自動検出 | × |
| Next.js 12–14 | 自動検出 | ○ (Compute platform) |
| Nuxt 3 | 自動検出 | ○ (Compute platform) |
| Angular | 自動検出 | × |
| Astro | 自動検出 | ○ (SSR モード) |
SSR 対応フレームワーク (Next.js / Nuxt) は Amplify の Compute platform を選択することで Lambda + CloudFront 構成でサーバーサイドレンダリングが有効になる。静的サイトと SSR を同一サービスで管理できる点が強みである。
6-2. Branch deploy — ブランチごとに環境を自動分離
Amplify Hosting ではリポジトリのブランチと 1:1 でデプロイ環境を自動構築する。ブランチを push するだけで独立した URL 付きの環境がプロビジョニングされるため、feature ブランチごとの動作確認が容易になる。
| ブランチパターン | 用途 | 自動生成 URL 例 |
|---|---|---|
main | 本番 | https://main.d1abc.amplifyapp.com |
develop | ステージング | https://develop.d1abc.amplifyapp.com |
feature/* | 機能開発 | https://feature-login.d1abc.amplifyapp.com |
enable_auto_build = true を設定すると新規ブランチの push 時点で環境が自動プロビジョニングされる。feature/* の glob パターンを指定することで命名規則に沿ったブランチを一括でデプロイ対象にできる。ブランチごとに異なる環境変数を設定できるため、本番・ステージング・開発環境の設定分離が Terraform だけで完結する。

6-3. Preview deploy — Pull Request ごとの確認 URL
Previews 機能を有効にすると、Pull Request を作成するたびに独立したプレビュー URL が自動発行される。フロントエンドレビューを PR 上で完結させられるため、ステージング環境への手動デプロイ作業が不要になる。
PR #42 open → https://pr-42.d1abc.amplifyapp.com が自動生成
PR #42 merge → preview 環境を自動削除 (設定要)
PR #42 close → preview 環境を自動削除 (設定要)
PR クローズ後のリソース残存を防ぐには、Amplify コンソール → App settings → Previews → 「Automatically delete Preview environments when a PR is closed」 を有効化する。Terraform では enable_pull_request_preview = true と pull_request_environment_name を合わせて指定し、PR クローズ時の自動削除が機能していることを確認する。
6-4. Custom Domain + Route 53 統合
カスタムドメインの紐付けは aws_amplify_domain_association で管理する。Amplify は ACM 証明書を自動発行・自動更新するため、手動で ACM を操作する必要はない。Route 53 ホストゾーンに Amplify が自動作成する CNAME レコードまたは Alias A レコードを登録することでサブドメインが有効化される。
domain_name に頂点ドメインを指定し、sub_domain ブロックで prefix = "" を設定することで Apex ドメイン直接割り当てが可能。
resource "aws_amplify_domain_association" "example" {
app_id= aws_amplify_app.frontend.id
domain_name = "example.com"
sub_domain {
branch_name = aws_amplify_branch.main.branch_name
prefix= "" # apex domain (example.com)
}
sub_domain {
branch_name = aws_amplify_branch.main.branch_name
prefix= "www" # www.example.com
}
sub_domain {
branch_name = aws_amplify_branch.develop.branch_name
prefix= "staging" # staging.example.com
}
}
6-5. amplify.yml — ビルドスペック詳細
Amplify のビルド設定はリポジトリルートの amplify.yml で管理する。CodeBuild の buildspec.yml に相当するが、フロントエンド特化の 4 フェーズ構成 (preBuild / build / postBuild / cache) を持つ。
version: 1
frontend:
phases:
preBuild:
commands:
- node --version
- npm ci --prefer-offline # node_modules キャッシュを活用
build:
commands:
- npm run build # Vite / CRA: dist/ へ出力
postBuild:
commands:
- echo "Build ID $AWS_JOB_ID complete"
artifacts:
baseDirectory: dist # Next.js の場合は .next
files:
- '**/*'
cache:
paths:
- node_modules/**/* # npm キャッシュ (ビルド高速化)
- .next/cache/**/*# Next.js ISR キャッシュ
Environment Variables / Secrets Manager 統合:
| 設定方法 | 用途 | 推奨 |
|---|---|---|
| Amplify Console → Environment variables | API エンドポイント URL 等の非機密値 | ○ |
aws_amplify_app.environment_variables | Terraform 管理の非機密環境変数 | ○ |
| Secrets Manager 参照 (Amplify Backend) | API Key / DB パスワード等の機密情報 | ○ (機密必須) |
amplify.yml へのハードコード | — | ✗ 禁止 |
ビルド時に $VITE_API_ENDPOINT 等の環境変数を参照する場合は Amplify コンソールまたは aws_amplify_app.environment_variables で一元管理する。機密情報は Secrets Manager に格納し、Amplify IAM ロール経由で参照する。
6-6. Terraform 完全例
# ── Amplify App 本体 ──────────────────────────────────────────
resource "aws_amplify_app" "frontend" {
name = "my-spa-app"
repository = "https://github.com/my-org/my-spa"
access_token = var.github_access_token
build_spec = <<-EOT
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: dist
files:
- '**/*'
cache:
paths:
- node_modules/**/*
EOT
environment_variables = {
VITE_API_ENDPOINT = "https://api.example.com"
NODE_ENV = "production"
}
custom_rule {
source = "/<*>"
status = "404"
target = "/index.html"
}
}
# ── main ブランチ (本番環境) ──────────────────────────────────
resource "aws_amplify_branch" "main" {
app_id= aws_amplify_app.frontend.id
branch_name = "main"
framework= "React"
stage = "PRODUCTION"
enable_auto_build = true
enable_pull_request_preview = false
environment_variables = {
VITE_ENV = "production"
}
}
# ── develop ブランチ (ステージング) ──────────────────────────
resource "aws_amplify_branch" "develop" {
app_id= aws_amplify_app.frontend.id
branch_name = "develop"
framework= "React"
stage = "DEVELOPMENT"
enable_auto_build = true
enable_pull_request_preview= true
pull_request_environment_name = "pr"
environment_variables = {
VITE_ENV = "staging"
}
}
# ── カスタムドメイン (Route 53 + ACM 自動統合) ───────────────
resource "aws_amplify_domain_association" "main" {
app_id= aws_amplify_app.frontend.id
domain_name = "example.com"
sub_domain {
branch_name = aws_amplify_branch.main.branch_name
prefix= ""
}
sub_domain {
branch_name = aws_amplify_branch.main.branch_name
prefix= "www"
}
sub_domain {
branch_name = aws_amplify_branch.develop.branch_name
prefix= "staging"
}
}
React Router / Vue Router を使った SPA で /dashboard など直接 URL にアクセスすると 404 が返る。CloudFront + S3 では ErrorDocument で対処するが、Amplify では Rewrites/Redirects (custom_rule) で解決する。
Terraform 設定: custom_rule { source = "/<*>" / status = "404" / target = "/index.html" }
Amplify コンソールでは「App settings → Rewrites and redirects」→ Source: /<*> / Target: /index.html / Type: 404 (Rewrite) を追加する。この設定を忘れると本番公開後にブックマーク・直リンクが全て 404 になる。デプロイ直後に必ず直接 URL アクセスの動作確認を実施すること。
6-7. Amplify Hosting vs CloudFront + S3 自前構築
| 観点 | Amplify Hosting | CloudFront + S3 自前構築 |
|---|---|---|
| セットアップ工数 | GitHub 連携のみ / 5 分 | Terraform 100 行以上 / OAC 設定必要 |
| ビルドパイプライン | 内蔵 (amplify.yml) | CodePipeline + CodeBuild を別途構築 |
| Branch / PR Preview | 標準機能 | 独自実装 (スタック / Lambda) が必要 |
| カスタムキャッシュ制御 | 制限あり (ヘッダー単位) | CloudFront Cache Policy で細粒度制御 |
| Edge Function | × | CloudFront Functions / Lambda@Edge |
| コスト (小〜中規模) | 低 (ビルド分数課金) | S3 + CloudFront 転送量課金 |
| 採用場面 | SPA / 静的サイト / SSR フロントエンド | Edge Logic / 独自 CDN ルール / 大規模 |
小〜中規模の SPA・静的サイトは Amplify Hosting が開発速度と運用コストの両面で有利。独自の Edge Logic や細粒度キャッシュ制御が必要な場合は CloudFront + S3 構成を選択する。
7. アンチパターン→正解パターン変換演習 (5件)
本節では、Container CD / CodeArtifact / SAM / Amplify の実際の設定でよく発生するアンチパターンを 5問提示します。
各演習は ■ Before (アンチパターン) → ■ After (正解パターン) → 解説 の 3部構成です。
演習1: ECS Blue/Green — Test traffic Listener Rule 設定漏れ (Terraform)
ECS Blue/Green デプロイでは、Production traffic を Green に切り替える前に Test traffic (ポート 8080) で
動作確認を行う Listener Rule が必要です。設定漏れがあると Green 環境の検証をスキップして
Production traffic が直接 Green に流れ込みます。
■ Before (アンチパターン)
resource "aws_codedeploy_deployment_group" "ecs_bg" {
app_name= aws_codedeploy_app.ecs.name
deployment_group_name = "ecs-production"
service_role_arn = aws_iam_role.codedeploy.arn
deployment_config_name = "CodeDeployDefault.ECSAllAtOnce"
ecs_service {
cluster_name = aws_ecs_cluster.main.name
service_name = aws_ecs_service.app.name
}
load_balancer_info {
target_group_pair_info {
prod_traffic_route {
listener_arns = [aws_lb_listener.https.arn]
}
# test_traffic_route が存在しない → Green 検証スキップ
target_group {
name = aws_lb_target_group.blue.name
}
target_group {
name = aws_lb_target_group.green.name
}
}
}
auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE"]
}
}
■ After (正解パターン)
resource "aws_lb_listener" "test" {
load_balancer_arn = aws_lb.main.arn
port = 8080
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.blue.arn
}
}
resource "aws_codedeploy_deployment_group" "ecs_bg" {
app_name= aws_codedeploy_app.ecs.name
deployment_group_name = "ecs-production"
service_role_arn = aws_iam_role.codedeploy.arn
deployment_config_name = "CodeDeployDefault.ECSAllAtOnce"
ecs_service {
cluster_name = aws_ecs_cluster.main.name
service_name = aws_ecs_service.app.name
}
load_balancer_info {
target_group_pair_info {
prod_traffic_route {
listener_arns = [aws_lb_listener.https.arn]
}
test_traffic_route {
listener_arns = [aws_lb_listener.test.arn]# ポート 8080 でテスト
}
target_group {
name = aws_lb_target_group.blue.name
}
target_group {
name = aws_lb_target_group.green.name
}
}
}
auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
}
}
解説:test_traffic_route を省略すると CodeDeploy は Green 検証フェーズをスキップして
Production traffic を直接 Green Target Group に切り替えます。
ポート 8080 の Test Listener を追加することで、デプロイ担当者が Green 環境をエンドツーエンドで
検証してから ContinueDeployment を実行できます。
Security Group に 8080 のインバウンドを許可することも忘れずに設定してください。
演習2: buildspec.yml — CodeArtifact login フェーズミス (YAML)
CodeArtifact の認証トークンは aws codeartifact get-authorization-token で取得しますが、build フェーズで実行すると pre_build の npm install 時点で認証がなく Dependency 解決が失敗します。
■ Before (アンチパターン)
version: 0.2
phases:
pre_build:
commands:
- npm ci # この時点で CodeArtifact 認証なし → 失敗
build:
commands:
- CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
--domain my-domain \
--domain-owner 123456789012 \
--query authorizationToken \
--output text)# install の後に認証実行 → 意味なし
- npm run build
- npm test
post_build:
commands:
- npm run package
artifacts:
files:
- "dist/**/*"
■ After (正解パターン)
version: 0.2
phases:
install:
commands:
- CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
--domain my-domain \
--domain-owner 123456789012 \
--query authorizationToken \
--output text)
- npm config set //my-domain-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/npm/my-repo/:_authToken $CODEARTIFACT_TOKEN
runtime-versions:
nodejs: 20
pre_build:
commands:
- npm ci # install フェーズで認証済みのため解決可能
build:
commands:
- npm run build
- npm test
post_build:
commands:
- npm run package
artifacts:
files:
- "dist/**/*"
解説:
CodeArtifact の認証トークンは有効期限が最大 12時間です。install フェーズで認証を完了させ、npm config に authToken を設定しておくことでpre_build の npm ci が CodeArtifact リポジトリから依存パッケージを解決できます。CODEARTIFACT_TOKEN 変数は環境変数として後続フェーズに引き継がれません。npm config set で永続化するか、各フェーズで再取得する必要があります。
演習3: SAM template.yaml — Lambda Alias DeploymentPreference Hooks 順序ミス (YAML)
SAM の DeploymentPreference では PreTrafficHook と PostTrafficHook の順序が重要です。
逆順にすると新バージョンの事前検証なしにトラフィックが切り替わります。
■ Before (アンチパターン)
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs20.x
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Hooks:
PostTrafficHook: !Ref ValidateAfterTraffic # 後検証を先に定義 (順序ミス)
PreTrafficHook: !Ref ValidateBeforeTraffic # 前検証が後に定義
ValidateBeforeTraffic:
Type: AWS::Serverless::Function
Properties:
Handler: validate_before.handler
Runtime: nodejs20.x
ValidateAfterTraffic:
Type: AWS::Serverless::Function
Properties:
Handler: validate_after.handler
Runtime: nodejs20.x
■ After (正解パターン)
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs20.x
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Hooks:
PreTrafficHook: !Ref ValidateBeforeTraffic # 前検証: 新バージョン起動確認
PostTrafficHook: !Ref ValidateAfterTraffic # 後検証: トラフィック切替後の動作確認
Alarms:
- !Ref FunctionErrorAlarm# エラー率アラームで自動ロールバック
ValidateBeforeTraffic:
Type: AWS::Serverless::Function
Properties:
Handler: validate_before.handler
Runtime: nodejs20.x
ValidateAfterTraffic:
Type: AWS::Serverless::Function
Properties:
Handler: validate_after.handler
Runtime: nodejs20.x
解説:PreTrafficHook は新バージョンの Lambda にトラフィックを流す前に実行されます。
ここでは新バージョンを直接呼び出してレスポンスを検証します。PostTrafficHook はトラフィック切替後の健全性確認です。
YAML の記述順序に関わらず CodeDeploy は Pre → Post の順で実行しますが、
意図を明確にするために Pre を先に記述する習慣を持つことで誤解を防げます。Alarms を追加することで CloudWatch Alarm 発火時に自動ロールバックが発動します。
演習4: amplify.yml — SPA Rewrites 設定漏れで Direct URL 404 (YAML)
React / Vue / Next.js などの SPA はクライアントサイドルーティングを使います。
Amplify Hosting でリライトルールを設定しないと、ブラウザから直接 /dashboard に
アクセスしたときにサーバーが index.html を返さず 404 になります。
■ Before (アンチパターン)
# amplify.yml — リライト設定なし
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: dist
files:
- '**/*'
cache:
paths:
- node_modules/**/*
# カスタムリライトルールが存在しない
# → /dashboard に直接アクセスすると S3 の dist/dashboard が存在せず 404
■ After (正解パターン)
# amplify.yml — SPA リライトルール追加
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: dist
files:
- '**/*'
cache:
paths:
- node_modules/**/*
上記の amplify.yml とあわせて、Amplify Console または Terraform で Rewrites ルールを設定します。
# Terraform: aws_amplify_app の custom_rule ブロック
resource "aws_amplify_app" "spa" {
name = "my-spa"
repository = "https://github.com/myorg/my-spa"
custom_rule {
source = "</^[^.]+$|\\.((?!css|gif|ico|jpg|js|png|txt|svg|woff|woff2|ttf|map|json)[^.]+)$/>"
target = "/index.html"
status = "200"# Rewrite (200 = URL維持してindex.htmlを返す)
}
}
解説:
SPA のクライアントサイドルーティングはブラウザの History API を使います。/dashboard のような URL は index.html を起点に React Router 等が処理しますが、
Amplify がそのパスを S3 オブジェクトとして探すと存在しないため 404 を返します。
リライトルール (status = "200") で全ての非アセットパスを index.html に転送することで、
クライアントサイドルーティングが正常に機能します。status = "301" はリダイレクトなので URL が変わってしまいます。必ず 200 (Rewrite) を使用してください。
演習5: ECR Lifecycle Policy — untagged/tagged 誤削除 (JSON)
ECR Lifecycle Policy で tagStatus: "any" を使うと、タグ付きイメージ (リリースバージョン) も
削除対象になります。untagged のみ削除したい場合は tagStatus: "untagged" に限定してください。
■ Before (アンチパターン)
{
"rules": [
{
"rulePriority": 1,
"description": "古いイメージを削除",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": {
"type": "expire"
}
}
]
}
■ After (正解パターン)
{
"rules": [
{
"rulePriority": 1,
"description": "untagged イメージを1件以上になったら削除",
"selection": {
"tagStatus": "untagged",
"countType": "imageCountMoreThan",
"countNumber": 1
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "タグ付きイメージは最新30件を保持",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v", "release-"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}
解説:tagStatus: "any" は untagged / tagged を問わず全イメージを対象にするため、countNumber: 10 を超えるとタグ付きリリースイメージも削除されます。tagStatus: "untagged" でビルド中間イメージのみを削除し、tagStatus: "tagged" + tagPrefixList で本番リリースイメージを最新 30件保持する
2ルール構成が推奨パターンです。ルールの優先度 (rulePriority) は数値が小さいほど先に評価されます。
§7 で扱う内容:
– 演習1: 壊れた ECS Blue/Green (Test traffic Listener Rule 設定漏れ → Production traffic に全量流入) を直す (Terraform)
– 演習2: 壊れた buildspec.yml (CodeArtifact login が phases.install で実行されず Dependency解決失敗) を直す (YAML)
– 演習3: 壊れた SAM template.yaml (Lambda Alias DeploymentPreference の Hooks 順序ミス) を直す (YAML)
– 演習4: 壊れた amplify.yml (SPA で Rewrites設定漏れ → Direct URL アクセスで 404) を直す (YAML + Console設定)
– 演習5: 壊れた ECR Lifecycle Policy (untagged image 削除が tagged image にも誤適用) を直す (JSON Policy)
– 各演習: アンチパターン Before / 正解 After / 解説の3部構成
– ep-btn: 演習解答アンカーリンク
– code×5 (HCL / YAML / YAML / YAML+console / JSON)
8. まとめ + Vol3予告 + 落とし穴10選 + 全10軸クロスリンク + Vol2完結宣言
本節では Vol2 の学習内容を整理し、よくある落とし穴と次のステップを示します。
Vol2 の振り返り
Vol1 (Pipeline/Build/Deploy/GHA) の基礎の上に、Vol2 では 4本柱を追加習得しました。
| 本柱 | 技術 | Vol2 のポイント |
|---|---|---|
| Container CD | ECS Blue/Green × EKS GitOps (ArgoCD/Flux) | Blue/Green Listener Rule / Sync wave / Canary |
| Package管理 | CodeArtifact × npm/Maven/pip統合 | ドメイン設計・認証トークン管理・upstream proxy |
| Serverless CD | SAM × Lambda Canary × DeploymentPreference | Hooks順序・Alarm自動ロールバック・Bootstrap設計 |
| Static CD | Amplify Hosting × Branch/Preview deploy | SPA Rewrites・環境変数管理・OAC設計 |
Vol2 の 4本柱は全て Vol1 の CodePipeline / CodeBuild / GitHub Actions OIDC を基盤として動作します。
Container → Package → Serverless → Static の4層が揃うことで、あらゆるアプリ形態の CI/CD を AWS でカバーできます。
落とし穴10選
Vol2 で頻出する落とし穴をまとめます。
- ECS Blue/Green Test traffic Listener Rule 漏れ — Production traffic が Green 検証スキップで直接流入
- EKS GitOps Sync wave 設定漏れ — 依存リソース (Namespace/CRD) がアプリより後にデプロイされる順序事故
- ECR Image Tag mutable のまま rollback —
latestタグが上書きされ旧バージョン Image が消失 - CodeArtifact 認証トークン期限切れ — 12時間後に CI が失敗。定期更新または都度取得の設計が必要
- SAM Bootstrap 重複実行で IAM Role 命名衝突 — 同一リージョン・同一アカウントで
sam deploy --guidedを複数回実行 - SAM Lambda Alias DeploymentPreference Hooks 順序ミス — PreTrafficHook なしにトラフィックが新バージョンへ切替
- Amplify Branch deploy で環境変数の上書き事故 — ブランチ固有の環境変数がアプリ全体に誤適用
- Amplify Preview deploy でリソース残存 — Pull Request クローズ後に Preview 環境が削除されず課金継続
- Amplify SPA Rewrites 設定漏れで Direct URL 404 — クライアントサイドルーティングで
index.htmlが返らない - CloudFront + S3 自前構築で OAC 設定漏れ — S3 バケットポリシーが Public になり直 S3 URL が露出
Vol3 予告 — Observability for CI/CD
Vol3 では CI/CD パイプライン自体の可観測性を扱います。
- Trace: X-Ray × OpenTelemetry で CodeBuild ビルドとデプロイの分散トレーシング
- Metrics: CloudWatch × Embedded Metrics Format で Pipeline 成功率・ビルド時間を可視化
- Cost最適化: CodeBuild スポットインスタンス活用・ARM ビルドへの移行・キャッシュ戦略最適化
- アラート: Pipeline 失敗を EventBridge → SNS → PagerDuty/Slack に自動通知する設計
Vol1/Vol2 で構築した CI/CD 基盤の品質を Observability で継続的に改善するサイクルを確立します。
本記事は全10軸シリーズのハブ記事として、各軸の本番運用知識を CI/CD 自動化基盤に接続します。
第1軸: IAM (4記事)
IAM ポリシー設計入門 Vol1 / IAM マルチアカウント設計 Vol2 / IAM 権限棚卸し自動化 Vol3 / IAM STS クロスアカウント Vol4
第2軸: EKS (3記事)
EKS 本番基盤構築 Vol1 / EKS 本番 Observability Vol2 / EKS GitOps×ArgoCD Vol3
第3軸: 復旧 (4記事)
DR 基礎設計 Vol1 / カオスエンジニアリング Vol2 / 障害対応自動化 Vol3 / マルチリージョン Active-Active Vol4
第4軸: AI (2記事)
Bedrock Agent 本番運用 Vol1 / Bedrock Knowledge Bases RAG Vol2
第5軸: セキュリティ (2記事)
AWS セキュリティ SOC 基盤 Vol1 / AWS セキュリティ運用 Vol2
第6軸: コスト (1記事)
AWS コスト最適化入門 Vol1
第7軸: マルチアカウント (1記事)
AWS マルチアカウント運用基礎 Vol1
第8軸: Observability (1記事)
AWS Observability 基礎 Vol1
第9軸: Network (2記事)
VPC ネットワーク設計入門 Vol1 / AWS ハイブリッドネットワーク Vol2
第10軸: DevOps/CI/CD実践 (本シリーズ)
Vol1: CodePipeline × CodeBuild × CodeDeploy × GitHub Actions OIDC
Vol2 (本記事): Container CD × CodeArtifact × SAM × Amplify
Vol3 (次回): Observability for CI/CD — Trace × Metrics × Cost最適化
第11軸: Database本番運用 (1記事)
Database本番運用入門 Vol1 — RDS × Aurora × DynamoDB
第10軸 DevOps/CI/CD実践シリーズ — Vol2 完結
本記事では、Vol1 で確立した CI/CD 基盤の上に Container CD / Package管理 / Serverless CD / Static CD の
4本柱を積み上げ、AWS でのあらゆるアプリ形態に対応できる本番品質の CI/CD を習得しました。
ECS Blue/Green の Test traffic 設計から EKS GitOps、CodeArtifact のパッケージ管理、
SAM の Canary デプロイ、Amplify の SPA ホスティングまで、5問の演習と落とし穴10選で実践力を養いました。
Vol3 では CI/CD パイプライン自体を観測・改善する Observability 基盤を構築します。
§8 で扱う内容:
– まとめ: 4本柱 (Container CD / Package管理 / Serverless CD / Static CD) 統合理解 + Vol1の上に乗る位置付け
– 落とし穴10選:
1. ECS Blue/Green の Test traffic Listener Rule 漏れ
2. EKS GitOps Sync wave 設定漏れ (依存リソース順序事故)
3. ECR Image Tag mutable のまま rollback で旧版消失
4. CodeArtifact 認証トークン期限切れ (12時間後の CI 失敗)
5. SAM Bootstrap 重複実行で IAM Role 命名衝突
6. SAM Lambda Alias DeploymentPreference Hooks 順序ミス
7. Amplify Branch deploy で環境変数の上書き事故
8. Amplify Preview deploy で Pull Request クローズ後の リソース残存
9. Amplify SPA Rewrites設定漏れで Direct URL 404
10. CloudFront + S3 自前構築での OAC 設定漏れ → 直 S3 URL 露出
– Vol3 予告: Observability for CI/CD — Trace × Metrics × Cost optimization
– 全10軸 (IAM4+EKS3+復旧4+AI2+セキュリティ2+コスト1+マルチアカウント1+Observability1+Network2+DevOps Vol1=21記事) + 本Vol2 = 22記事 クロスリンク ep-box (brc-blue)
– 第10軸 シリーズ Vol2 完結宣言