AWS CI/CD入門Vol1|Pipeline×Build×Deploy×GitHub Actions

目次

DevOps/CI/CD実践入門 Vol1 — CodePipeline × CodeBuild × CodeDeploy × GitHub Actions OIDC

fig01: DevOps 4本柱全体図 (CodePipeline/CodeBuild/CodeDeploy/GitHub Actions)

AWS本番運用シリーズ – 第10軸 DevOps/CI/CD実践 シリーズ起点 Vol1
本記事は AWS本番運用 9軸 (20記事) を完遂した中堅エンジニアに向けた、第10軸 = DevOps/CI/CD実践 の起点記事です。CodePipeline × CodeBuild × CodeDeploy × GitHub Actions OIDC の4本柱を全9軸統合視点で再統合し、本番品質の自動化基盤を構築します。

前9軸シリーズ (20記事)

  • IAM Vol1-4 / EKS Vol1-3 / 復旧 Vol1-4 / AI Vol1-2 / セキュリティ Vol1-2 / コスト Vol1 / マルチアカウント Vol1 / Observability Vol1 / Network Vol1-2

関連シリーズ (CI/CD 個別 deep-dive)

  • AWS Code* ファミリー Vol1 (overview), Vol2 (CodeBuild deep-dive), Vol3 (CodePipeline V2+CodeDeploy)
  • Terraform team CI/CD Vol2 (GHA+OIDC), Vol3 (CodePipeline+CodeBuild)

1. なぜDevOps / CI/CDか — 全9軸からの架橋 + 第10軸結節点

全9軸 (IAM / EKS / 復旧 / AI / セキュリティ / コスト / マルチアカウント / Observability / Network) のシリーズを読了した読者には、共通の問いが残ります。「学んだ9軸の知識を、実際の本番環境にどう継続的・安全に届けるか」。どれほど優れたIAMポリシーを設計しても、EKS Clusterを本番仕様で構築しても、その成果物をデプロイするプロセスが手動のままでは、設計の価値は半減します。この問いに答えるのが DevOps / CI/CD であり、本Vol1が起点となる第10軸です。

1-1. 全9軸の知識を本番に運ぶ自動化基盤としてのCI/CD

CI/CD (Continuous Integration / Continuous Delivery) は、コードの変更を自動的にビルド・テスト・デプロイする仕組みです。第10軸である DevOps/CI/CD 実践は、前9軸で積み上げた知識を 実際の本番環境に自動的かつ安全に運ぶ自動化基盤 として機能します。

前9軸の各成果物 (Terraform moduleファイル / Docker Image / EKSマニフェスト / IAM Policy JSON) は、本番環境への自動化された経路がなければ毎回の手動適用が必要になります。CI/CDパイプラインが介在することで、これらの成果物はレビュー→テスト→デプロイの自動化フローに乗ります。

既存軸CI/CD との連動ポイント
IAM (Vol1-4)Pipeline実行IAM Role / OIDC連携 Trust Policy / CodeBuild実行権限 / Cross-Account Assume Role
EKS (Vol1-3)EKS への Blue/Green Deploy / kubectl 自動化 / Helm Chart CI / ECR Push → ECS Task更新
復旧設計 (Vol1-4)自動ロールバック戦略 / Blue/Green切替によるゼロダウンタイム更新 / Multi-Region Deploy順序制御
AI (Vol1-2)Lambda / ECS への AI推論モデルの自動デプロイ / モデルバージョン管理 / 推論エンドポイント更新
セキュリティ (Vol1-2)Pipeline内脆弱性スキャン / コンプライアンスゲート / コンテナイメージ署名検証
コスト (Vol1)CodeBuild スポット活用 / Pipeline実行コスト最適化 / 不要Artifactのライフサイクル管理
マルチアカウント (Vol1)Cross-Account Pipeline (Dev→Staging→Prod) / 環境別Artifact Promotion / AWS RAM活用
Observability (Vol1)デプロイ後メトリクス監視 / EventBridge通知連携 / デプロイ前後の異常検知・自動ロールバック
Network (Vol1-2)CodeBuild VPC接続 / Private Subnet内ビルド / VPCエンドポイント経由のECR/S3アクセス

1-2. 手動デプロイが生む4つの痛点

DevOps/CI/CD が必要になる背景には、手動運用が生む構造的な問題があります。本節では本番環境で頻出する4つの痛点を整理します。

痛点① 人為ミスと再現性の欠如

手動デプロイでは、担当者がコマンドを手打ちする工程が必ず存在します。ステージング環境でのコマンドと本番環境でのコマンドが微妙に異なる、環境変数の貼り間違い、対象リージョンの誤選択など、手作業は人為ミスの温床です。

「先週のデプロイと同じ手順で」という指示があっても、手順書が更新されていない・担当者が変わっている・環境が微妙に変化しているという状況では、完全な再現は困難です。夜間の本番デプロイで手順を1つ飛ばして気づかない、というケースは珍しくありません。

CI/CDパイプラインでは、すべての手順をコードとして定義します。buildspec.yml / appspec.yml / GitHub Actions Workflow ファイルが 単一の真実のソース (Single Source of Truth) となり、実行結果の再現性が保証されます。デプロイ履歴はパイプライン実行ログとして自動記録されるため、監査証跡も自然に残ります。

痛点② 全9軸の知識が本番に自動で届かない

IAM最小権限設計・Terraform IaC・EKSマニフェスト管理など、9軸で積み上げた成果物は、本番環境への自動化された経路がなければ 毎回の手動適用が必要 になります。

変更を手動で反映するたびに、設定漏れ・適用順序の誤り・ロールバック不能な状態変化のリスクが生まれます。特に複数のAWSリソースが連携する変更 (IAM Roleの更新 + ECSタスク定義の更新 + CodeDeploy設定の変更) を手動で同期させる作業は、経験豊富なエンジニアでも失敗します。

CI/CDは、これらの成果物 (Terraform planファイル / Docker Image / Lambda Zip) をパイプラインで一元管理し、レビュー・テスト・デプロイを自動化します。各ステップにIAM権限チェックが組み込まれ、9軸で設計したセキュリティポリシーが自動で適用されます。

痛点③ ステージング→本番の手動コピペ作業リスク

「ステージングで動作確認したものを本番に同じ手順で適用する」という要件でも、手動では確認項目が増えるほどミスが生まれます。本番固有の設定値を上書きする、staging用の設定を本番に混入させる、バージョン番号を手動で書き換えるといった作業は、自動化なしには確実に再現できません

Pipeline の Artifact Promotion パターン (Staging → Pre-Production → Production の順でArtifactを昇格) を導入することで、「同じビルド成果物」が環境を渡るため、ステージングで検証した内容と本番デプロイが完全に一致します。環境固有の設定値は Secrets Manager や Parameter Store から実行時に注入することで、Artifact自体は環境非依存に保てます。

痛点④ ロールバック手順の属人化

本番障害発生時に「前バージョンに戻す手順」が特定エンジニアの頭の中にしかない状態は、深刻なリスクです。不在時の遅延・手順の誤り・判断の遅れは、システムダウンタイムを直接延長させます。

CodeDeploy の Auto Rollback / Blue/Green切替 / GitHub Actions の Environment Protection Rules を組み合わせることで、ロールバック手順をコードに落とし込み、誰でも実行できる自動化を実現します。ロールバック基準 (エラーレート閾値 / CloudWatchアラーム) も設定ファイルとして管理できるため、深夜の障害対応でも判断が一貫します (§5で詳述)。

痛点⑤ デプロイ頻度の低さと開発サイクルの停滞

手動デプロイの工数が高い環境では、チームは自然と「まとめてデプロイ」を選ぶようになります。週1回・月1回の大型リリースでは、変更の規模が大きくなるため障害リスクが増大し、障害発生時の原因特定も困難になります。

「小さく頻繁にリリースする」という DevOps の核心的なプラクティスは、デプロイプロセスが自動化されていなければ実現できません。CI/CDパイプラインにより1日に複数回のデプロイが安全に実行できる環境を整えることで、フィードバックループが短縮され、開発速度と品質の両方が向上します。

比較軸手動デプロイ運用CI/CD自動化後
デプロイ頻度週1〜月1回 (リスク集中)1日数回〜数日に1回 (リスク分散)
1回あたりの変更量大規模 (複数機能一括)小規模 (単機能単位)
障害時の影響範囲広い (多数の変更が混在)狭い (単一変更に特定)
原因特定の速度遅い (変更量が多い)速い (変更差分が明確)
ロールバック難易度高い (手順複雑/属人化)低い (自動化/コード管理)

1-3. 本記事で得られる4つの成果

本Vol1を読了することで、以下の4つの成果を得られます。

成果① DevOps 3本柱の統合理解

ビルド自動化 / テスト自動化 / デプロイ自動化の3本柱と、それを支えるAWSサービスマップを体系的に理解できます。CodePipeline / CodeBuild / CodeDeploy / GitHub Actions の4本柱が3本柱のどのフェーズを担うかを、統合視点で把握できます (§2)。

成果② CodePipeline 本番設計

Source → Build → Test → Deploy → 手動承認 / EventBridge通知 の全ステージを、実際の設計判断軸とTerraform例で理解できます。Cross-Account Pipeline (Dev→Staging→Prod) の設計パターンも含みます (§3)。

成果③ Build / Deploy 選定軸の習得

CodeBuild vs GitHub Actions ランナー / CodeDeploy Blue/Green vs In-Place vs Canary の選定基準を、サービス種別 (ECS / Lambda / EC2) × リスク許容度のマトリクスで整理できます。buildspec.yml の実装例と appspec.yml のHooks設計も習得できます (§4 / §5)。

成果④ GitHub Actions × AWS OIDC実装

最小権限のTrust Policy設計 / assume-role-with-web-identity / Workflow分割設計を、実際に動く実装として理解できます。アクセスキーを使わないセキュアなAWS連携の標準パターンを身につけられます (§6)。

CI/CD導入前後の変化を俯瞰すると、技術的な自動化だけでなく、チームのデリバリー文化そのものが変わることが分かります。

比較観点CI/CD導入前CI/CD導入後
デプロイ担当特定の上級エンジニアのみチーム全員がパイプライン経由で実行可能
デプロイ実行時間数時間〜1日 (手作業)数分〜数十分 (自動化)
テスト実行手動・不定期PRごとに自動実行
環境間の差異属人的なセットアップで発生しやすいArtifactが統一・環境変数は動的注入
監査証跡作業ログが残らない / 不完全パイプライン実行ログが自動記録
障害対応ロールバック手順を個人が判断・手動実行Auto Rollback / 設定ファイルで自動実行
開発速度デプロイ恐怖心からリリース間隔が広がりがち小さく頻繁なリリースが安全に実現

1-4. 既存シリーズとの住み分け

本Vol1は既存のCI/CD関連記事とスコープを分担しています。各記事はdeep-dive対象が異なるため、重複するのではなく相互補完の関係にあります。本文中で詳細が不要な箇所は既存記事へのクロスリンクで誘導します。

既存記事スコープ本Vol1との関係
AWS Code* ファミリー Vol1サービス選定・GHA比較本Vol1は全9軸統合視点で再統合。詳細はそちらへ
AWS Code* ファミリー Vol2CodeBuild deep-dive (buildspec/VPC/マルチアーキ)本Vol1§4は選定軸まで。詳細はそちらへ
AWS Code* ファミリー Vol3CodePipeline V2 + ECS Blue/Green 本番運用本Vol1§3・§5は基礎設計まで。応用はそちらへ
Terraform team CI/CD Vol2GHA × Terraform OIDC本Vol1§6はアプリCI/CD OIDC。IaC専用OIDCはそちらへ
Terraform team CI/CD Vol3CodePipeline × Terraform WorkflowTerraform専用。本Vol1はアプリCI/CD中心

本Vol1の独自性は 「全9軸統合視点 + 第10軸シリーズ起点 + アプリCI/CD中心」 の3軸にあります。各deep-dive記事と組み合わせることで、AWS DevOpsの完全な知識体系が得られます。

1-5. 第10軸 DevOps/CI/CD実践シリーズの起点として

本Vol1は、DevOps/CI/CD実践シリーズの起点 (Vol1) として位置づけられます。前9軸で積み上げた知識の 「本番運用への最終接続レイヤー」 であり、全9軸20記事のハブとして機能します。

シリーズ計画スコープ
Vol1 (本記事): 全9軸架橋 + 4本柱基礎 + OIDC実装基礎から本番品質の自動化基盤を構築
Vol2 (次巻予定): CodePipeline 高度設計 + Multi-Account + Cross-Regionエンタープライズ規模のPipeline設計
Vol3 (予定): GitHub Actions × AWS 高度活用 + Self-hosted RunnerGHAネイティブ環境での本番CI/CD

以降では§2でAWS DevOps 3本柱とサービスマップを整理し、§3以降の実践設計解説に繋げます。

1-6. 本記事を効果的に読み進めるための前提知識

本Vol1は全9軸いずれかのシリーズ読了者を主な対象としていますが、初めてCI/CDに触れる方でも理解できるよう、基礎から体系的に解説します。以下の前提知識があると、より深く内容を吸収できます。

前提知識レベル感本Vol1での活用場面
AWS IAM 基礎ロール/ポリシーの概念が分かる§3 Pipeline実行ロール / §6 OIDC Trust Policy
Terraform 基礎resource / variable / output が書ける§3 CodePipeline Terraform例 / §4 CodeBuild例
Docker 基礎Dockerfile を書いてイメージをビルドできる§4 CodeBuild + Docker マルチアーキビルド
Git 基礎ブランチ / PR の概念が分かる§3 Source stage / §6 GitHub Actions trigger
AWS CLI 操作aws コマンドで基本操作ができる§7 演習での検証

これらの前提知識に不安がある場合は、本シリーズの関連記事 (IAM Vol1 / Terraform team CI/CD Vol2) を先に読んでから本記事に進むことを推奨します。

本記事の推奨読み方:
初見: §1-§2 (概論) → §3 (Pipeline) → §5 (Deploy) → §6 (OIDC) → §7 (演習) の順で通読
特定機能のみ: 各節は独立して参照可能。例: OIDC設定に困ったら§6だけを読む
実装時: §3-§6 のTerraform例をコピーして環境に合わせてカスタマイズ


2. AWS DevOps 3本柱整理 — ビルド / テスト / デプロイ自動化 + サービスマップ

記事冒頭の fig01 (DevOps 4本柱全体図) はCodePipeline / CodeBuild / CodeDeploy / GitHub Actions の4本柱が、ビルド・テスト・デプロイの各フェーズをどう担うかを示しています。本節では、その全体図の構造を3本柱の定義から読み解きます。

2-1. DevOps 3本柱の定義

DevOpsにおける自動化は、以下の3本柱で構成されます。

① ビルド自動化 — コードを成果物へ

ソースコードを実行可能な成果物 (Artifact) に変換するプロセスを自動化します。

成果物の種類説明主なビルドツール
Docker Imageコンテナアプリケーション実行単位CodeBuild / GitHub Actions + Docker
JAR / WARJava アプリケーション実行ファイルCodeBuild + Maven / Gradle
Lambda ZIPサーバーレス関数パッケージCodeBuild / GitHub Actions + SAM CLI
CloudFormation テンプレートIaC デプロイ単位CodeBuild + cfn-lint
Terraform Plan ファイルIaC 変更計画CodeBuild / GitHub Actions + Terraform
npm / pip パッケージフロントエンド / ライブラリ成果物CodeBuild / GitHub Actions + npm / pip

ビルドは 再現性が命 です。同じソースコードから、いつ誰がビルドしても同一の成果物が生成されることを保証することが、CI/CD全体の信頼性の基盤となります。

② テスト自動化 — 品質ゲートの自動化

ビルドした成果物を本番に届ける前に、品質と安全性を自動検証します。複数種別のテストを組み合わせることで、本番到達前の品質保証を多層化します。

テスト種別内容ツール例
ユニットテスト関数/クラス単位の動作検証Jest / pytest / JUnit
統合テストサービス間連携の動作検証Testcontainers / LocalStack
E2Eテストユーザーシナリオの端から端まで検証Playwright / Cypress
脆弱性スキャンコンテナイメージ・依存ライブラリの既知脆弱性検出Trivy / Snyk
Linting/静的解析コード品質・設定ミスの検出ESLint / tflint / cfn-lint / Checkov

CodeBuild の reports 機能を使うと、テスト結果レポートをAWSコンソール上で可視化・履歴管理できます。テストが失敗した場合はPipelineが自動停止し、不合格の成果物が本番へ進むことを防ぎます。

③ デプロイ自動化 — 成果物を本番へ安全に届ける

検証済みの成果物を、ターゲット環境に安全かつ再現可能な方法で適用します。デプロイ戦略の選択は、サービスの可用性要件と障害対応速度のトレードオフで決まります。

デプロイ戦略説明適用サービスダウンタイム
In-Place既存インスタンスをそのまま更新EC2 / オンプレミスあり (短時間)
Blue/Green新環境を並走させてトラフィックを切替ECS / Lambda / EC2ほぼなし
Canary一部トラフィックのみ新バージョンへ段階移行Lambda (CodeDeploy)なし
Rollingインスタンスを順次更新EKS / EC2 Auto Scalingなし (部分的)

2-2. AWS DevOps サービスマップ

AWS が提供する DevOps 関連サービスを、3本柱のフェーズ別に整理します。

ビルドフェーズのサービス

AWS CodeBuild

AWSフルマネージドのビルドサービスです。Dockerコンテナ内でビルドが実行されるため、ビルド環境の再現性が保証されます。buildspec.yml でビルド手順を定義し、install / pre_build / build / post_build の4フェーズで構成されます。

主要な機能:
VPCモード: Private Subnet内でビルドを実行し、社内リポジトリやRDSへ安全にアクセス
Secrets Manager連携: ビルド時の認証情報をハードコードせず動的取得
マルチアーキテクチャビルド: arm64 / x86_64 の複数アーキテクチャに対応した Docker Image を同時ビルド
テストレポート: JUnit/NUnit形式のテスト結果をAWSコンソールで可視化・履歴保持

buildspec.yml の基本構造は4フェーズで構成されます (詳細は§4で解説):

version: 0.2

phases:
  install:
 runtime-versions:
nodejs: 20  # ランタイムのインストール
 commands:
- npm install  # 依存ライブラリのインストール

  pre_build:
 commands:
- aws ecr get-login-password | docker login --username AWS# ECR認証
- npm run lint # 静的解析

  build:
 commands:
- npm run test # ユニットテスト実行
- docker build -t $IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER . # イメージビルド
- docker push $IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER

  post_build:
 commands:
- printf '[{"name":"app","imageUri":"%s"}]' $IMAGE_REPO_NAME:$CODEBUILD_BUILD_NUMBER > imagedefinitions.json

artifacts:
  files:
 - imagedefinitions.json# ECSデプロイ用Artifact

GitHub Actions (GitHub-hosted ランナー)

GitHubが管理するランナーで実行するCI/CDワークフローです。ubuntu-latest / macos-latest / windows-latest を無料枠内で利用可能です。AWSとの連携はOIDC (OpenID Connect) を使った一時認証が標準です (§6で詳述)。パブリックリポジトリは実行時間無制限、プライベートリポジトリは月2,000分まで無料です。

GitHub Actions (Self-hosted ランナー)

AWSのEC2インスタンスやEKS Pod をランナーとして登録する方式です。以下のシナリオで有効です:
– VPCアクセスが必要なビルド (Private Subnetのリソースへのアクセス)
– 特定のインスタンスタイプが必要な処理 (GPU / 高メモリ)
– コスト最適化 (Spot Instanceの活用で大幅コスト削減)
– ランナーイメージの完全カスタマイズが必要な場合

テストフェーズのサービス

サービス主な用途
CodeBuild (テストフェーズ)ユニット/統合テスト実行・reports機能によるテスト結果可視化
GitHub Actionsテストワークフロー実行 (OIDC連携でAWSリソースへのE2Eテスト)
ECR イメージスキャンコンテナイメージのプッシュ時に脆弱性を自動スキャン

ECRのイメージスキャンはプッシュ時に自動実行されるため、ビルドパイプラインへの追加コードなしにコンテナ脆弱性の継続監視が可能です。

デプロイフェーズのサービス

サービス適用ターゲット特徴
CodeDeployEC2 / ECS / LambdaBlue/Green / In-Place / Canary 対応 / appspec.yml でHook管理
CloudFormationインフラリソース全般テンプレートでの宣言的デプロイ / Change Set による変更確認
AWS CDK Deployインフラリソース全般TypeScript/Python でのIaC / CloudFormation 上位互換
Terraform Applyマルチクラウド対応インフラHCL宣言型IaC / plan/apply の2段階確認 / state管理
ECS Task DeployECSサービス更新タスク定義の更新 + サービスのローリングアップデート

オーケストレーションのサービス

AWS CodePipeline

AWSネイティブのCI/CDオーケストレーションサービスです。Source / Build / Test / Deploy / Approval のステージをGUI + Terraform で定義できます。2023年のV2リリースから実行単価課金 (パイプライン実行回数単位) に変更され、コスト予測が容易になりました。

CodePipelineの強みは AWSサービスとのネイティブ統合 にあります。IAM Role / S3 Artifact / KMS暗号化 / CloudWatch Events との連携が追加設定なしで動作し、マルチアカウント環境での権限分離も実現しやすい構成になっています。

GitHub Actions Workflows

.github/workflows/*.yml でワークフローを定義します。Push / PR / Schedule / Manual (workflow_dispatch) トリガーをサポートします。Environment ごとのProtection Rulesで承認フローを実装でき、デプロイ先環境の保護が可能です。

Reusable Workflows (workflow_call) を活用することで、複数リポジトリ間でワークフロー定義を再利用でき、組織全体のCI/CDベストプラクティスを標準化できます。

Amazon EventBridge

デプロイイベント (CodePipeline成功/失敗/承認待ち) をトリガーにSlack通知・Lambda実行・PagerDuty連携などを行うイベントバスです。Observability軸 (Vol1) で構築した通知基盤と連携することで、デプロイ状況の可視化が一元化されます。

2-3. 4本柱の統合理解

本Vol1が扱うDevOps 4本柱 (CodePipeline / CodeBuild / CodeDeploy / GitHub Actions) を、役割と連携の観点で整理します。

4本柱 選定マトリクス

| | CodePipeline | GitHub Actions | CodeBuild | CodeDeploy |
|—|—|—|—|—|
| 主な役割 | パイプライン オーケストレーション | CI/CD統合 ワークフロー | ビルド・テスト 実行エンジン | デプロイ 実行エンジン |
| AWS統合深度 | ◎ ネイティブ統合 | ○ OIDC連携が必要 | ◎ ネイティブ統合 | ◎ ネイティブ統合 |
| OSS/GitHub 親和性 | △ GitHub連携はOAuth | ◎ GitHubネイティブ | △ Git操作不可 | △ appspec.yml がAWS独自 |
| コスト体系 | $1/実行 (V2) | 無料枠+分単位 | $0.005/分〜 | デプロイ実行無料 |
| 向いているシナリオ | AWSサービス間の複雑な連携 | GitHubリポジトリ中心のCI | 多様なビルド環境が必要な場合 | 高度なデプロイ戦略 |

2-4. 選定軸 — 統合度 / コスト / 組織構造の3軸

4本柱のどれを選ぶかは、以下の3軸で判断します。

軸① AWS統合深度

AWSサービスとのネイティブ統合が深い順: CodePipeline ≧ CodeBuild = CodeDeploy > GitHub Actions

CodePipeline は S3 Artifact / KMS暗号化 / IAM Role / CloudWatch Events をネイティブに扱います。GitHub Actions はOIDC連携が必要ですが、一度設定すれば IAM一時認証でほぼ同等の操作が可能です (§6で詳述)。マルチアカウント環境ではCodePipelineのCross-Account Role連携が有利です。

軸② コスト構造

選択肢コスト特性向いているワークロード
CodePipeline V2$1/パイプライン実行月100回以下のデプロイ / AWSオールイン環境
CodeBuild$0.005/分〜 (small)短時間ビルドが多い場合 / Spot有効で60%削減
GitHub Actions hosted無料枠 (パブリック: 無制限 / プライベート: 2000分/月)OSS / 小規模チーム
GHA Self-hostedEC2コスト + ランナー管理コストSpot Instance活用で大幅なコスト削減が可能

軸③ 組織構造とリポジトリ戦略

組織パターン推奨ツール理由
AWSリソース管理が主体 / 少人数チームCodePipeline + CodeBuildAWSコンソールで一元管理、学習コスト最小
GitHub中心のOSS/SaaS開発GitHub ActionsGitHubのPR/Issue/Actionsで一気通貫
AWS + GitHub 混在 / ハイブリッドGitHub Actions (CI) + CodeDeploy (Deploy)OIDC連携でCI/CDを跨ぐ
大規模マルチアカウントCodePipeline + Cross-Account RoleAWS Organizations との権限管理の相性が良い

2-5. §1-§2 のまとめと以降の章構成

§1・§2で確立した概念フレームワークをもとに、§3以降では各本柱を実践的に解説します。

扱う内容§2との接続ポイント
§3 CodePipelineステージ設計 + Artifact + 手動承認 + EventBridgeオーケストレーション本柱の実践
§4 CodeBuildbuildspec / Secrets / VPC / Custom Imageビルド本柱の選定軸と実装
§5 CodeDeployBlue/Green / Hooks / Auto Rollback / appspec.ymlデプロイ本柱の実践 (山場2)
§6 GitHub ActionsOIDC Trust Policy / assume-role / Workflow分割GitHub中心のCI/CD 実践

全9軸の知識を本番に運ぶ自動化基盤の実装に向けて、§3のCodePipeline設計実践から着手します。

2-6. CodePipeline + CodeBuild + CodeDeploy の連携フロー

3サービスの連携パターンを理解することで、以降の実装解説をスムーズに読み進められます。標準的なECSアプリケーションのCI/CDフローは以下の構成が一般的です。

[開発者] → git push → [CodeCommit/GitHub]
↓ トリガー
[CodePipeline Stage 1: Source]
  - ソースコードをS3 Artifact Bucketに格納
↓
[CodePipeline Stage 2: Build]
  - CodeBuild: buildspec.yml を実行
 ① 依存ライブラリインストール
 ② ユニットテスト実行 → JUnitレポート生成
 ③ Docker イメージビルド → ECR プッシュ
 ④ imagedefinitions.json を Artifact 出力
↓ テスト失敗時はここで停止
[CodePipeline Stage 3: Approval (任意)]
  - 手動承認: レビュアーがコンソールで承認/拒否
  - EventBridge → SNS → メール通知
↓
[CodePipeline Stage 4: Deploy]
  - CodeDeploy: ECS Blue/Green デプロイ
 ① 新タスク定義を登録
 ② Blue環境 (現本番) を維持しつつGreen環境を起動
 ③ ALBのトラフィックをGreenへ切替
 ④ 安定稼働を確認後にBlueを停止

各ステージ間でArtifactはS3バケット (KMS暗号化) を経由して引き渡されます。ステージが失敗した場合、後続ステージは自動的にスキップされ、失敗ステージのログが CloudWatch Logs に記録されます。

このパターンが理解できていれば、§3-§5のTerraform実装例を読む際に各リソースの役割が把握しやすくなります。


3. CodePipeline 設計実践 ★山場1 — ステージ/Artifacts/手動承認/EventBridge

3-1. CodePipeline V2 の進化点 — 並列実行 / 条件分岐 / 変数サポート

AWS CodePipeline V2 は 2023年 GA となり、V1 から大幅に機能強化された。新規 Pipeline はすべて V2 タイプを選択する。 V1 は引き続き動作するが機能追加の対象外だ。

機能V1V2
並列アクション実行同一ステージ内のみステージ間でも並列実行可能
条件分岐非対応ルール条件によるステージスキップ
Pipeline 変数非対応パイプライン/アクションレベル変数
トリガーフィルタリングブランチのみブランチ/タグ/ファイルパスでフィルタ
料金体系アクション実行分数課金Pipeline 実行数課金 (多くの場合 V1 より低コスト)

V2 変数の活用例: #{variables.IMAGE_TAG} 構文で Docker イメージタグを Source トリガー時に注入し、Build/Deploy ステージ全体で参照できる。環境ごとにパイプラインを複製せず、変数で挙動を切り替えるパターンが主流だ。

3-2. ステージ設計の全体像

CodePipeline ステージ設計 + Artifacts フロー — Source/Build/Test/Approval/Deploy

本番 Pipeline の標準構成は 5ステージ から成る。

Source → Build → Test → Manual Approval → Deploy

各ステージは 1 つ以上の アクション で構成される。同一ステージ内の複数アクションは並列または直列に実行できる。ステージ間の成果物 (Artifacts) は S3 Artifact Bucket 経由で受け渡される。

graph LR
  A[Source<br/>GitHub] --> B[Build<br/>CodeBuild]
  B --> C[Test<br/>CodeBuild]
  C --> D{Manual<br/>Approval}
  D -->|承認| E[Deploy<br/>CodeDeploy]
  D -->|却下| F[停止]

3-3. Source ステージ — GitHub / S3

Source ステージはリポジトリの変更を検知してソースコードを Artifact 化する。

GitHub 接続 (CodeStarSourceConnection):

action {
  name = "GitHub_Source"
  category= "Source"
  owner= "AWS"
  provider= "CodeStarSourceConnection"
  version = "1"
  output_artifacts = ["source_output"]

  configuration = {
 ConnectionArn = aws_codestarconnections_connection.github.arn
 FullRepositoryId = "my-org/my-app"
 BranchName = "main"
 DetectChanges = "true"
  }
}

V2 のトリガーフィルタリングにより、特定パス (src/**) やタグ (v*) 変更のみ Pipeline を起動できる。docs/** 変更による無駄な実行を抑制しコスト最適化につながる。

S3 Source: CloudFormation テンプレートや Lambda ZIP を S3 に配置するパターン。S3 PUT イベントを EventBridge でキャプチャして Pipeline をトリガーする。

3-4. Build ステージ — CodeBuild アクション

Build ステージでは CodeBuild プロジェクトを実行してコンパイル・ユニットテスト・Docker ビルド・Artifact 生成を担う。

action {
  name = "Build"
  category= "Build"
  owner= "AWS"
  provider= "CodeBuild"
  version = "1"
  input_artifacts  = ["source_output"]
  output_artifacts = ["build_output"]

  configuration = {
 ProjectName = aws_codebuild_project.main.name
 EnvironmentVariables = jsonencode([
{ name = "DEPLOY_ENV",  value = "production",type = "PLAINTEXT" },
{ name = "DB_PASSWORD", value = "/prod/db/password",  type = "PARAMETER_STORE" }
 ])
  }
}

Build ステージの出力 build_output が S3 Artifact Bucket に格納され、後続の Test/Deploy ステージへ受け渡される。buildspec.yml の構造と Secrets Manager 連携の詳細は §4 で解説する。

3-5. Test ステージ — 統合テストとレポート

Build ステージと Test ステージを分離すると、テスト失敗時の原因特定が容易になる。

action {
  name= "Integration_Test"
  category  = "Test"
  owner  = "AWS"
  provider  = "CodeBuild"
  version= "1"
  input_artifacts = ["build_output"]

  configuration = {
 ProjectName = aws_codebuild_project.integration_test.name
  }
}

CodeBuild Reports で JUnit XML 形式のレポートを生成すると、Pipeline 実行履歴とテスト合否が紐付く。デグレの回帰追跡が Pipeline 画面から直接できるため、障害対応の初動スピードが向上する。

3-6. Manual Approval ステージ — 承認ゲートと SNS 通知

本番デプロイ前の人的確認ゲートは Approval アクション で実現する。SNS トピックの指定が 必須 で、未設定のまま運用すると承認者が気づかず Pipeline が放置される (詰まりポイント第2位)。

action {
  name  = "Prod_Approval"
  category = "Approval"
  owner = "AWS"
  provider = "Manual"
  version  = "1"

  configuration = {
 NotificationArn = aws_sns_topic.pipeline_approvals.arn
 CustomData= "本番デプロイを承認してください。変更概要: #{variables.CHANGE_SUMMARY}"
 ExternalEntityLink = "https://github.com/my-org/my-app/compare/main"
  }
}

承認タイムアウト: デフォルト 7 日。タイムアウト超過は自動 Rejection となり Pipeline が停止する。実運用では 24〜48 時間へ短縮するポリシーが多い。Slack Webhook 連携で SNS → Lambda → Slack に転送し、ボタン操作で承認/却下するパターンが本番標準だ。

3-7. Deploy ステージ — プロバイダー選定

Deploy プロバイダーは対象サービスで使い分ける。

プロバイダー対象代表ユースケース
CodeDeployEC2 / LambdaEC2 In-Place / Blue-Green / Lambda Canary
CloudFormation任意 AWS リソースIaC スタックの継続的デプロイ
ECSFargate / EC2 タスクECS Blue/Green (CodeDeploy 連携)
S3静的コンテンツS3 + CloudFront 静的サイト

ECS Blue/Green の appspec.yml・Hooks・Auto Rollback の詳細は §5 および AWS Code* ファミリー Vol3 で完全解説している。

3-8. Artifacts フロー — S3 Artifact Bucket / KMS 暗号化 / Cross-Account

Artifact Bucket の設計は Pipeline の安定性とセキュリティの根幹だ。

設計原則:
1. 専用バケット: Pipeline ごとに Artifact 専用バケットを作成する。他用途との混在は権限設計を複雑化する
2. KMS CMK 暗号化: デフォルト AES256 ではなく Customer Managed Key を使用する。Cross-Account Pipeline では CMK が必須
3. ライフサイクルポリシー: 30 日で古い Artifact を自動削除してコストを抑制する

resource "aws_s3_bucket" "artifact" {
  bucket  = "my-pipeline-artifacts-${data.aws_caller_identity.current.account_id}"
  force_destroy = false
}

resource "aws_s3_bucket_server_side_encryption_configuration" "artifact" {
  bucket = aws_s3_bucket.artifact.id

  rule {
 apply_server_side_encryption_by_default {
sse_algorithm  = "aws:kms"
kms_master_key_id = aws_kms_key.pipeline.arn
 }
 bucket_key_enabled = true
  }
}

resource "aws_s3_bucket_lifecycle_configuration" "artifact" {
  bucket = aws_s3_bucket.artifact.id

  rule {
 id  = "expire-artifacts"
 status = "Enabled"
 expiration { days = 30 }
  }
}

Cross-Account Pipeline: KMS キーポリシーに宛先アカウントの CodeDeploy/CodeBuild Service Role を追加し、S3 バケットポリシーでも Cross-Account アクセスを許可する。CMK なしでは 403 エラーが発生する。

3-9. EventBridge 連携 — Pipeline 状態変化通知

Pipeline の FAILED/SUCCEEDED イベントを EventBridge でキャプチャし SNS/Lambda に転送する。

resource "aws_cloudwatch_event_rule" "pipeline_state" {
  name  = "codepipeline-execution-state-change"
  description = "CodePipeline 実行状態変化を検知"

  event_pattern = jsonencode({
 source  = ["aws.codepipeline"]
 "detail-type" = ["CodePipeline Pipeline Execution State Change"]
 detail = {
state = ["FAILED", "SUCCEEDED"]
pipeline = [aws_codepipeline.main.name]
 }
  })
}

resource "aws_cloudwatch_event_target" "notify_sns" {
  rule= aws_cloudwatch_event_rule.pipeline_state.name
  target_id = "SendToSNS"
  arn = aws_sns_topic.pipeline_alerts.arn
}

detail.stagedetail.action フィールドを条件に追加すると、どのステージで失敗したかを Lambda で判定して Slack に整形メッセージを送れる。Observability Vol1 の CloudWatch Alarms 設計と組み合わせると障害の全体把握が容易になる。

3-10. IAM ロール最小権限設計 — Pipeline Service Role と役割分離

Pipeline に関わる IAM ロールは用途ごとに分離する。

resource "aws_iam_role" "pipeline" {
  name = "codepipeline-service-role"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "codepipeline.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy" "pipeline" {
  role = aws_iam_role.pipeline.id
  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect= "Allow"
  Action= ["s3:GetObject", "s3:PutObject", "s3:GetBucketVersioning"]
  Resource = [aws_s3_bucket.artifact.arn, "${aws_s3_bucket.artifact.arn}/*"]
},
{
  Effect= "Allow"
  Action= ["codebuild:BatchGetBuilds", "codebuild:StartBuild"]
  Resource = aws_codebuild_project.main.arn
},
{
  Effect= "Allow"
  Action= [
 "codedeploy:CreateDeployment", "codedeploy:GetDeployment",
 "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision"
  ]
  Resource = "*"
},
{
  Effect= "Allow"
  Action= ["kms:GenerateDataKey", "kms:Decrypt"]
  Resource = aws_kms_key.pipeline.arn
},
{
  Effect= "Allow"
  Action= ["codestar-connections:UseConnection"]
  Resource = aws_codestarconnections_connection.github.arn
}
 ]
  })
}

ロール分離の原則: Pipeline Service Role はオーケストレーション権限のみ持つ。実ビルドや Deploy の操作権限は CodeBuild/CodeDeploy 各 Service Role に委任する。Pipeline Role に AdministratorAccess を付与することは最頻出のアンチパターンだ (§7 演習で修正する)。

失敗事例: Artifact Bucket 暗号化漏れ → Deploy 失敗
S3 Artifact Bucket に server_side_encryption_configuration を設定しないと、CodeDeploy が Artifact を取得できず Deploy ステージが失敗します。KMS キーを指定する場合は Deploy Service Role に kms:Decrypt 権限も必要です。Cross-Account Pipeline では「Access Denied」エラーの原因の大半がこの設定漏れです。

  • 確認コマンド: aws s3api get-bucket-encryption --bucket YOUR_ARTIFACT_BUCKET
  • 確認コマンド: aws iam simulate-principal-policy --policy-source-arn ROLE_ARN --action-names kms:Decrypt --resource-arns KEY_ARN

クロスリンク: ECS Blue/Green や Lambda Canary の詳細設計は AWS Code* ファミリー Vol3 — CodePipeline V2+CodeDeploy 本番運用 で完全解説している。マルチアカウント Cross-Account Pipeline 設計は マルチアカウント運用 Vol1 も参照。


4. CodeBuild 実践 — buildspec / 環境変数 / Secrets Manager / VPC接続 / Custom Image

4-1. CodeBuild の位置付け — 3つの利用パターン

CodeBuild はフルマネージドの継続的インテグレーションサービス。ビルド環境のプロビジョニング・スケーリング・廃棄をすべて AWS が担う。

利用パターン特徴選定目安
CodePipeline Build stagePipeline と統合。Artifacts を自動受け渡しAWS ネイティブパイプライン構築時
スタンドアロン CIGitHub/Bitbucket Webhook → CodeBuild 直接起動CodePipeline 不要の軽量 CI
GitHub Actions self-hosted runner 代替OIDC 連携不要、VPC 内リソースへのアクセスが容易プライベートサブネット内の DB/ECS へのテスト要件

GitHub Actions との選定軸:
GitHub 中心のチーム: GitHub Actions が自然 (OIDC 連携で §6 参照)
AWS ネイティブで統一したい: CodeBuild + CodePipeline で閉じる
VPC 内リソースへのテストが必要: CodeBuild の VPC 接続が簡便

4-2. buildspec.yml v0.2 完全理解

version: 0.2

env:
  variables:
 APP_ENV: "production"
  parameter-store:
 DB_HOST: "/myapp/prod/db_host"
  secrets-manager:
 API_KEY: "myapp/prod/api_key:api_key"

phases:
  install:
 runtime-versions:
nodejs: 20
 commands:
- npm ci --prefer-offline
  pre_build:
 commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
- echo "Pre-build phase: $CODEBUILD_BUILD_NUMBER"
  build:
 commands:
- npm run build
- npm test
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker push $ECR_REGISTRY/$IMAGE_REPO_NAME:$IMAGE_TAG
  post_build:
 commands:
- echo "Build completed: $(date)"
- printf '[{"name":"app","imageUri":"%s"}]' $ECR_REGISTRY/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files:
 - imagedefinitions.json
 - appspec.yml
  discard-paths: no
  secondary-artifacts:
 test-reports:
files:
  - "coverage/**/*"
base-directory: .

cache:
  paths:
 - node_modules/**/*

reports:
  jest-test-reports:
 files:
- "junit.xml"
 file-format: JUNITXML

env ブロックの環境変数 3 タイプ:

タイプ記法用途注意点
variablesKEY: value非機密の静的値ビルドログに平文で出力される
parameter-storeKEY: "/path/to/param"Parameter Store の SecureStringIAM 権限 ssm:GetParameters 必要
secrets-managerKEY: "secret-name:json-key"Secrets Manager のシークレットIAM 権限 secretsmanager:GetSecretValue 必要

4-3. VPC 接続 — プライベートリソースへのアクセス

CodeBuild を VPC 内で実行することで、RDS や ElastiCache などプライベートサブネットのリソースにアクセスできる。

設計指針:
– Private Subnet + NAT Gateway を推奨 (ECR や S3 へのアウトバウンド通信に必要)
– Public Subnet は非推奨 (セキュリティリスク)
– Security Group: Inbound 不要、Outbound は必要なポートのみ許可

resource "aws_codebuild_project" "app" {
  name = "app-build"
  description= "Application build project"
  service_role  = aws_iam_role.codebuild.arn
  build_timeout = 60

  artifacts {
 type = "CODEPIPELINE"
  }

  environment {
 compute_type = "BUILD_GENERAL1_SMALL"
 image  = "aws/codebuild/standard:7.0"
 type= "LINUX_CONTAINER"
 image_pull_credentials_type = "CODEBUILD"
 privileged_mode = true

 environment_variable {
name  = "ECR_REGISTRY"
value = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com"
 }
  }

  source {
 type = "CODEPIPELINE"
  }

  vpc_config {
 vpc_id  = aws_vpc.main.id
 subnets = [aws_subnet.private_az1.id, aws_subnet.private_az2.id]
 security_group_ids = [aws_security_group.codebuild.id]
  }

  cache {
 type  = "S3"
 location = "${aws_s3_bucket.build_cache.id}/cache"
  }

  logs_config {
 cloudwatch_logs {
group_name  = "/codebuild/app-build"
stream_name = ""
 }
  }

  tags = {
 Name = "app-build"
  }
}

resource "aws_iam_role" "codebuild" {
  name = "codebuild-service-role"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "codebuild.amazonaws.com" }
 }]
  })
}

resource "aws_iam_role_policy_attachment" "codebuild_policy" {
  role = aws_iam_role.codebuild.name
  policy_arn = "arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess"
}

4-4. Custom Image とマルチアーキテクチャ対応

標準イメージ vs Custom Image:

選択肢メリットユースケース
aws/codebuild/standard:7.0AWS 管理、Node 20/Python 3.12/Java 21 対応一般的なアプリケーションビルド
ECR-hosted Custom Image社内ライブラリ・ツール込み / 起動高速化特殊な依存関係 / ビルド時間削減

マルチアーキテクチャ:

environment {
  compute_type = "BUILD_GENERAL1_LARGE"
  image  = "aws/codebuild/standard:7.0"
  type= "ARM_CONTAINER"  # ARM64 ビルド
}

LINUX_CONTAINER (x86_64) と ARM_CONTAINER を使い分けることで、Graviton 向けのコンテナイメージを生成できる。

4-5. CodeBuild テストレポートと通知

CodeBuild は JUnit / Cucumber / TestNG 形式のテストレポートを自動収集して CodeBuild コンソール上に表示できる。CI 失敗時のデバッグを大幅に効率化する。

reports:
  jest-coverage:
 files:
- "coverage/junit.xml"
 file-format: JUNITXML
  cucumber-report:
 files:
- "reports/cucumber.json"
 file-format: CUCUMBERJSON

CloudWatch Events でビルド失敗を通知:

resource "aws_cloudwatch_event_rule" "codebuild_failure" {
  name  = "codebuild-build-failure"
  description = "CodeBuild ビルド失敗時に通知"

  event_pattern = jsonencode({
 source= ["aws.codebuild"]
 detail-type = ["CodeBuild Build State Change"]
 detail = {
build-status = ["FAILED"]
project-name = ["app-build"]
 }
  })
}

resource "aws_cloudwatch_event_target" "sns" {
  rule= aws_cloudwatch_event_rule.codebuild_failure.name
  target_id = "send-to-sns"
  arn = aws_sns_topic.alerts.arn
}

4-6. Secrets Manager 参照のセキュリティ設計

buildspec.yml の secrets-manager タイプで参照する場合、Secrets Manager のシークレットは JSON 形式で保存し、JSON キーを指定して個別の値を取得できる。

{
  "api_key": "sk-xxxxxxxxxxxxxx",
  "db_password": "P@ssw0rd123!"
}

buildspec.yml での参照:

env:
  secrets-manager:
 API_KEY: "myapp/prod/credentials:api_key"
 DB_PASSWORD: "myapp/prod/credentials:db_password"

IAM 権限設計: CodeBuild Service Role に以下を付与する。

resource "aws_iam_role_policy" "codebuild_secrets" {
  name = "codebuild-secrets-access"
  role = aws_iam_role.codebuild.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect= "Allow"
  Action= ["secretsmanager:GetSecretValue"]
  Resource = ["arn:aws:secretsmanager:ap-northeast-1:*:secret:myapp/prod/*"]
},
{
  Effect= "Allow"
  Action= ["kms:Decrypt"]
  Resource = [aws_kms_key.secrets.arn]
}
 ]
  })
}
buildspec.yml の落とし穴: cache は S3 vs LOCAL

cache: { type: LOCAL } はビルドインスタンスのローカルのみ有効で、スケールアウト時には消えます。依存ライブラリキャッシュを本番で活かすには type: S3 + バケット指定が必要です。

注意点:

  • S3 キャッシュ: 複数のビルドインスタンスで共有可能。ただし大きなキャッシュは S3 転送時間が増加しコストも発生する
  • LOCAL キャッシュ: 同一ビルドインスタンスの再利用時のみ有効。スポット中断で無効化される
  • 推奨: Docker Layer Cache は LOCAL_DOCKER_LAYER_CACHE、npm/pip は S3 の組み合わせが実用的

5. CodeDeploy 実践 ★山場2 — Blue/Green / In-Place / Hooks / Auto Rollback / appspec.yml

5-1. CodeDeploy 概要 — 3 つの対象プラットフォーム

CodeDeploy はアプリケーションのデプロイを自動化するサービス。EC2/オンプレミス、ECS、Lambda の 3 プラットフォームに対応し、戦略によってダウンタイムを最小化する。

プラットフォーム対応戦略特徴
EC2 / オンプレIn-Place / Blue/GreenAgent インストール必要。アプリのライフサイクルを Hook で制御
ECSBlue/Green のみALB Target Group の重み付きルーティングで無停止切替
LambdaCanary / Linear / All-at-Onceエイリアスの重み付きルーティングで段階的移行

5-2. デプロイ戦略選定マトリクス

戦略対象ロールバック速度コストリスク推奨場面
Blue/GreenECS / Lambda高速 (ALB 重み切替)やや高 (2 環境課金)本番 ECS サービス / ゼロダウンタイム要件
In-PlaceEC2 AutoScaling遅い (再デプロイ必要)開発・ステージング / コスト優先
CanaryLambda Alias高速 (重み付き)最低Lambda 関数の段階的リリース
LinearLambda Alias高速一定間隔でトラフィック移行したい場合

Blue/Green の仕組み (ECS):
1. Green 環境 (新バージョン) を新しい ECS Task Definition でデプロイ
2. ALB Target Group B に Green タスクを登録
3. テスト用ポート (8080) で Green を検証
4. ALB のトラフィックを Blue (旧) から Green (新) へ切替
5. 問題なければ Blue 環境を破棄

5-3. appspec.yml — デプロイ定義ファイル

appspec.yml はデプロイ手順とライフサイクルフックを定義する。EC2 用と ECS 用で構造が異なる。

EC2 用 appspec.yml:

version: 0.0
os: linux
files:
  - source: /build
 destination: /var/www/html
  - source: /config/nginx.conf
 destination: /etc/nginx/nginx.conf
permissions:
  - object: /var/www/html
 pattern: "**"
 owner: www-data
 group: www-data
 mode: 755
 type:
- directory
hooks:
  BeforeInstall:
 - location: scripts/stop_server.sh
timeout: 30
runas: root
  AfterInstall:
 - location: scripts/install_dependencies.sh
timeout: 120
runas: ec2-user
  ApplicationStart:
 - location: scripts/start_server.sh
timeout: 60
runas: root
  ValidateService:
 - location: scripts/validate_service.sh
timeout: 60
runas: ec2-user

ECS 用 appspec.yml:

version: 0.0
Resources:
  - TargetService:
Type: AWS::ECS::Service
Properties:
  TaskDefinition: <TASK_DEFINITION>
  LoadBalancerInfo:
 ContainerName: "app"
 ContainerPort: 8080
  PlatformVersion: "LATEST"
Hooks:
  - BeforeAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789012:function:pre-traffic-hook"
  - AfterAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789012:function:post-traffic-hook"

5-4. Auto Rollback — 自動ロールバックのトリガー

CodeDeploy の Auto Rollback は以下の条件で発動する:

トリガー説明
CloudWatch Alarm指定したアラームが ALARM 状態になった場合
デプロイ失敗Hook スクリプトが非ゼロ終了 / タイムアウト
手動ロールバックコンソール / CLI からの明示的な操作
resource "aws_codedeploy_deployment_group" "app" {
  app_name  = aws_codedeploy_app.app.name
  deployment_group_name = "app-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]
}
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"]
  }

  alarm_configuration {
 alarms  = [aws_cloudwatch_metric_alarm.error_rate.name]
 enabled = true
  }

  blue_green_deployment_config {
 deployment_ready_option {
action_on_timeout = "CONTINUE_DEPLOYMENT"
wait_time_in_minutes = 0
 }
 terminate_blue_instances_on_deployment_success {
action= "TERMINATE"
termination_wait_time_in_minutes = 5
 }
  }

  tags = {
 Name = "app-production-deployment-group"
  }
}

5-5. Blue/Green デプロイタイムライン

fig03: CodeDeploy Blue/Green 切替 + Hooks フロー

gantt
  title Blue/Green Deploy タイムライン
  dateFormat mm:ss
  section Blue (旧本番)
 本番トラフィック 100% :active, blue1, 00:00, 05:00
 トラフィック 0% :blue2, 05:00, 10:00
 Terminate (5分後)  :crit, blue3, 10:00, 11:00
  section Green (新バージョン)
 ECS Task 起動完了:green1, 00:00, 02:00
 BeforeAllowTraffic Hook :green2, 02:00, 03:30
 ALB 切替 (本番100%):active, green3, 03:30, 10:00
 AfterAllowTraffic Hook :green4, 03:30, 05:00
Hook 失敗パターン: ValidateService timeout → 自動ロールバック

ValidateService スクリプトが timeout 秒内に exit 0 を返さない場合、CodeDeploy は自動ロールバックを実行します。

よくある原因と対策:

  • アプリ起動完了前のヘルスチェック: validate.sh にリトライループ (最大60秒) を実装し、起動猶予時間を確保する
  • ヘルスチェックパスの変更忘れ: ALB Target Group のヘルスチェック設定と一致しているか確認する
  • Hook スクリプトの権限エラー: runas ユーザーがスクリプトの実行権限を持っているか確認する
  • ECS の BeforeAllowTraffic Hook Lambda 失敗: Lambda 関数のタイムアウトを 5 分以上に設定し、CloudWatch Logs でエラーを確認する

5-6. In-Place デプロイ — EC2 AutoScaling との連携

In-Place はデプロイ対象のインスタンスを停止せずに新バージョンに置き換える。コストは安いが切り戻しに時間がかかる。

デプロイフロー:
1. AutoScaling Group の ELB 接続を一時解除 (トラフィック停止)
2. CodeDeploy Agent が新バージョンをインスタンスに配置
3. ApplicationStart Hook でアプリを起動
4. ValidateService でヘルスチェック成功後、ELB に再接続

失敗時のロールバック手順:
In-Place は旧バージョンのアーティファクトを保持しているため、手動で前回のリビジョンを再デプロイする。Blue/Green より時間がかかる。

# 直前のリビジョンへ手動ロールバック
aws deploy create-deployment \
  --application-name app \
  --deployment-group-name app-production \
  --description "Manual rollback to previous version" \
  --previous-revision-override \
 revisionType=S3,s3Location="{bucket=my-bucket,key=app-v1.zip,bundleType=zip}"

5-7. Lambda Canary / Linear デプロイ

Lambda の CodeDeploy 組み込み戦略により、エイリアスのトラフィック重み付けを段階的に移行できる。

設定値説明使用場面
LambdaCanary10Percent5Minutes10% → 5分後 → 100%短時間での段階確認
LambdaLinear10PercentEvery1Minute10% → 1分ごとに10%増緩やかな移行
LambdaAllAtOnce即時100%切替テスト環境 / 低リスク関数
resource "aws_codedeploy_app" "lambda_app" {
  compute_platform = "Lambda"
  name = "my-lambda-app"
}

resource "aws_codedeploy_deployment_group" "lambda" {
  app_name= aws_codedeploy_app.lambda_app.name
  deployment_group_name  = "lambda-production"
  service_role_arn = aws_iam_role.codedeploy.arn
  deployment_config_name = "CodeDeployDefault.LambdaCanary10Percent5Minutes"

  auto_rollback_configuration {
 enabled = true
 events  = ["DEPLOYMENT_FAILURE"]
  }

  alarm_configuration {
 alarms  = [aws_cloudwatch_metric_alarm.lambda_errors.name]
 enabled = true
  }
}

appspec.yml (Lambda 用) で BeforeAllowTraffic / AfterAllowTraffic Hook を使うと、カナリアトラフィック中に動作確認用の Lambda を実行できる。


6. GitHub Actions × AWS OIDC連携 — Trust Policy / assume-role / Workflow分割

6-1. GitHub Actions vs CodePipeline — 選定軸

GitHub Actions と AWS CodePipeline はどちらも CI/CD パイプラインを構築できるが、組織の技術スタックや AWS 統合要件によって適切な選択が異なる。

比較軸GitHub ActionsCodePipeline
向いている場面OSS-first / GitHub 中心組織AWS サービス統合重視
コスト無料枠あり (2,000分/月) + 分単位課金パイプライン実行単位課金 ($1/本/月〜)
AWS 統合深度OIDC 経由の STS 一時認証ネイティブ IAM Role 連携
ランナー管理GitHub-hosted / Self-hosted 選択可AWS が完全管理
エコシステムActions Marketplace (8,000+ アクション)AWS 限定プラグイン
Terraform との親和性Workflow YAML でステップ制御CodePipeline + CodeBuild 組み合わせ

GitHub 中心の開発チームで Infrastructure as Code を Terraform で管理している場合、GitHub Actions + OIDC 認証が最も自然な構成になる。本節では GitHub Actions × AWS OIDC 連携に絞って解説する。CodePipeline との詳細比較は §3 を参照。

6-2. OIDC 概念 — 静的 Access Key 廃止から短命 STS Token へ

なぜ静的 Access Key を廃止するか

従来の CI/CD では IAM User の Access Key を GitHub Secrets に保存してパイプラインから AWS を操作していた。この構成には 3 つのリスクがある。

  1. 漏洩リスク: Access Key は一度発行すると無効化しない限り永続する。Secrets のローテーション漏れや Actions ログへの誤出力で漏洩が起きる。
  2. ローテーション管理コスト: 定期的な Access Key のローテーションには IaC 側の更新と Secrets の更新が必要で、運用負担が大きい。
  3. 最小権限の困難さ: 1 本の Access Key に複数パイプラインの権限をまとめやすく、権限過剰になりがち。

OIDC (OpenID Connect) を使うと、GitHub Actions がトークンを生成して AWS STS に渡し、短命の一時認証情報 (STS Token) を取得する。STS Token は数時間で自動失効するため、漏洩しても攻撃可能時間が極端に短い。

GitHub → AWS STS の認証フロー

[GitHub Actions Runner]
│ 1. OIDC Token を GitHub OIDC Provider に要求
▼
[GitHub OIDC Provider (token.actions.githubusercontent.com)]
│ 2. 署名済み JWT を発行 (sub / aud / iss クレームを含む)
▼
[AWS STS: AssumeRoleWithWebIdentity]
│ 3. JWT の署名を OIDC Provider 公開鍵で検証
│ 4. Trust Policy の条件 (sub / aud) を評価
▼
[一時的な IAM Role 認証情報 (STS Token: 最長1時間)]
│ 5. Workflow ステップが STS Token で AWS API を呼び出す
▼
[AWS サービス (ECR / S3 / ECS / Lambda 等)]

fig04: GitHub Actions OIDC Trust Policy + assume-role フロー

6-3. AWS IAM OIDC Provider 設定

GitHub Actions の OIDC を AWS で受け入れるには、まず IAM に OIDC Provider を登録する。

resource "aws_iam_openid_connect_provider" "github" {
  url = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]

  tags = {
 Name = "github-actions-oidc"
  }
}
  • url: GitHub の OIDC エンドポイント (固定値)
  • client_id_list: sts.amazonaws.com 固定 (audience クレームと一致させる)
  • thumbprint_list: GitHub OIDC 証明書チェーンの thumbprint (AWS Console から自動取得可)
# 登録済み OIDC Provider の確認
aws iam list-open-id-connect-providers \
  --query 'OpenIDConnectProviderList[*].Arn' \
  --output table

6-4. IAM Role Trust Policy 設計

OIDC Provider 登録後、GitHub Actions が AssumeRoleWithWebIdentity できる IAM Role を作成する。Trust Policy の設計がセキュリティの要となる。

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Principal": {
  "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
  "StringEquals": {
 "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
 "token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/main"
  }
}
 }
  ]
}

sub クレームでリポジトリとブランチを絞り込む点が最重要。sub の形式は repo:{org}/{repo}:ref:{ref} または repo:{org}/{repo}:environment:{env}StringEquals で具体的なブランチ名を指定し、ワイルドカード使用は避ける。

Terraform での実装:

data "aws_iam_policy_document" "github_actions_trust" {
  statement {
 effect  = "Allow"
 actions = ["sts:AssumeRoleWithWebIdentity"]

 principals {
type  = "Federated"
identifiers = [aws_iam_openid_connect_provider.github.arn]
 }

 condition {
test  = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values= ["sts.amazonaws.com"]
 }

 condition {
test  = "StringEquals"
variable = "token.actions.githubusercontent.com:sub"
values= ["repo:myorg/myrepo:ref:refs/heads/main"]
 }
  }
}

resource "aws_iam_role" "github_actions_deploy" {
  name= "github-actions-deploy"
  assume_role_policy = data.aws_iam_policy_document.github_actions_trust.json
}

resource "aws_iam_role_policy_attachment" "github_actions_deploy" {
  role = aws_iam_role.github_actions_deploy.name
  policy_arn = aws_iam_policy.deploy_policy.arn
}
落とし穴: sub クレームにワイルドカードで全ブランチ許可してしまう事例
Trust Policy の sub クレームを StringLike + repo:myorg/myrepo:ref:refs/heads/* のようにワイルドカードで指定すると、feature ブランチや任意の PR からも本番 AWS へのアクセスが可能になります。悪意のある PR 経由で本番環境への操作が行われるリスクがあります。

StringEquals + 具体的なブランチ名 (refs/heads/main) に絞るか、環境別 Role (dev-role / stg-role / prod-role) を分けて GitHub Environments の environment:production クレームで本番 Role を保護することを強く推奨します。

6-5. GitHub Actions Workflow YAML 例

name: Deploy to AWS
on:
  push:
 branches: [main]

permissions:
  id-token: write# OIDC Token 取得に必須
  contents: read # リポジトリ読み取り

jobs:
  deploy:
 runs-on: ubuntu-latest
 steps:
- uses: actions/checkout@v4

- name: Configure AWS credentials via OIDC
  uses: aws-actions/configure-aws-credentials@v4
  with:
 role-to-assume: arn:aws:iam::ACCOUNT_ID:role/github-actions-deploy
 aws-region: ap-northeast-1

- name: Verify identity
  run: aws sts get-caller-identity

- name: Build and push container image
  run: |
 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 myapp:latest .
 docker push ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest

permissions: id-token: write が必須である点に注意。これを省略すると OIDC Token が生成されず、configure-aws-credentials が認証に失敗する。また role-to-assume には ARN 形式でロールを指定する。Access Key は一切不要。

6-6. Workflow 分割パターン

大規模なパイプラインでは、Workflow を役割ごとに分割する設計が保守性を高める。

PR 駆動 vs main merge 駆動の分離

# .github/workflows/pr-check.yml — PR 時: lint + plan のみ (readonly Role)
name: PR Check
on:
  pull_request:
 branches: [main]
permissions:
  id-token: write
  contents: read
  pull-requests: write
jobs:
  plan:
 runs-on: ubuntu-latest
 steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
  with:
 role-to-assume: arn:aws:iam::ACCOUNT_ID:role/github-actions-readonly
 aws-region: ap-northeast-1
- run: terraform fmt -check && terraform validate
- run: terraform plan -no-color 2>&1 | tee plan.txt
- uses: actions/github-script@v7
  with:
 script: |
const fs = require('fs')
const plan = fs.readFileSync('plan.txt', 'utf8')
github.rest.issues.createComment({
  issue_number: context.issue.number,
  owner: context.repo.owner,
  repo: context.repo.repo,
  body: '```\n' + plan.slice(0, 60000) + '\n```'
})
# .github/workflows/deploy.yml — main merge 時: apply まで実行 (deploy Role)
name: Deploy
on:
  push:
 branches: [main]
permissions:
  id-token: write
  contents: read
jobs:
  deploy:
 runs-on: ubuntu-latest
 environment: production# GitHub Environments Protection Rules を適用
 steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
  with:
 role-to-assume: arn:aws:iam::ACCOUNT_ID:role/github-actions-deploy
 aws-region: ap-northeast-1
- run: terraform apply -auto-approve

環境別 Role の使い分け

環境Role 名sub クレーム条件権限スコープ
devgithub-actions-devref:refs/heads/feature/*S3/ECR 書き込み
stggithub-actions-stgref:refs/heads/mainECS Staging デプロイ
prodgithub-actions-prodenvironment:productionECS 本番デプロイ

本番環境には GitHub Environments の Protection Rules (Required Reviewers / Deployment Branches) を組み合わせることで、main へのマージ後もさらに人手承認ゲートを設けられる。

Terraform team を対象にした Plan/Apply 分離の詳細は「GitHub Actions+OIDC Terraform CI/CD 完全ガイド」で解説している。


7. アンチパターン→正解パターン変換演習 (5件)

本節では、実際の CI/CD 設定でよく発生するアンチパターンを 5問提示します。
各演習は ■ Before (アンチパターン)■ After (正解パターン)解説 の 3部構成です。


演習1: CodePipeline Artifact Bucket — KMS暗号化漏れ (Terraform)

S3 Artifact Bucket に KMS暗号化を設定せずに Pipeline を構築すると、
Deploy ステージの実行ロールに kms:Decrypt 権限がない場合に Deploy が失敗します。
Pipeline の作成時点ではエラーが出ないため、初回デプロイで初めて発覚するパターンです。

■ Before (アンチパターン)

resource "aws_codepipeline" "main" {
  name  = "my-pipeline"
  role_arn = aws_iam_role.pipeline.arn

  artifact_store {
 location = aws_s3_bucket.artifacts.bucket
 type  = "S3"
 # encryption_key ブロックが存在しない
 # → S3 デフォルト暗号化 (SSE-S3) のみ
  }

  stage {
 name = "Source"
 action {
name = "Source"
category= "Source"
owner= "ThirdParty"
provider= "GitHub"
version = "1"
output_artifacts = ["source_output"]
configuration = {
  Owner= "myorg"
  Repo = "myapp"
  Branch  = "main"
  OAuthToken = var.github_token
}
 }
  }
}

■ After (正解パターン)

resource "aws_kms_key" "pipeline_artifacts" {
  description = "KMS key for CodePipeline artifact bucket"
  deletion_window_in_days = 30
  enable_key_rotation  = true
}

resource "aws_codepipeline" "main" {
  name  = "my-pipeline"
  role_arn = aws_iam_role.pipeline.arn

  artifact_store {
 location = aws_s3_bucket.artifacts.bucket
 type  = "S3"

 encryption_key {
id= aws_kms_key.pipeline_artifacts.arn
type = "KMS"
 }
  }

  stage {
 name = "Source"
 action {
name = "Source"
category= "Source"
owner= "ThirdParty"
provider= "GitHub"
version = "1"
output_artifacts = ["source_output"]
configuration = {
  Owner= "myorg"
  Repo = "myapp"
  Branch  = "main"
  OAuthToken = var.github_token
}
 }
  }
}

解説:
S3 デフォルト暗号化 (SSE-S3) でも Artifact は保存できますが、Pipeline の各ステージ実行ロールに
kms:Decrypt / kms:GenerateDataKey 権限が必要になります。
encryption_key ブロックを追加し、Pipeline Service Role と Deploy Role 双方に KMS 権限を付与することで根治できます。
Cross-Region Pipeline を構築する場合は、各リージョンに KMS キーをそれぞれ作成する必要がある点にも注意してください。


演習2: buildspec.yml — phases インデントミス + cache設定漏れ (YAML)

buildspec.yml のインデントが 1 文字ずれると該当フェーズが無視されます。
CodeBuild のログに「フェーズ未実行」と表示されるのに原因を特定できず詰まるケースが多いです。

■ Before (アンチパターン)

version: 0.2

phases:
  install:
 runtime-versions:
nodejs: 20
  pre_build:
commands:  # インデントが1段余分 (install と揃っていない)
  - npm ci
  build:
 commands:
- npm run build
- npm test

artifacts:
  files:
 - "dist/**/*"
# cache ブロックが存在しない → node_modules を毎回ダウンロード

■ After (正解パターン)

version: 0.2

phases:
  install:
 runtime-versions:
nodejs: 20
  pre_build:
 commands: # install と同レベル (2スペース)
- npm ci
  build:
 commands:
- npm run build
- npm test

cache:
  type: S3
  location: my-codebuild-cache-bucket/npm-cache
  paths:
 - node_modules/**/*

artifacts:
  files:
 - "dist/**/*"

解説:
phases 直下の install / pre_build / build / post_build は同一インデントレベルです。
pre_buildcommands が親より深いインデントになると、YAML パーサーが commands を認識できず、フェーズが空実行になります。
cache ブロックを追加すると node_modules が S3 にキャッシュされ、2回目以降のビルド時間を大幅に短縮できます。
version: 0.1version: 0.2 の構造差異にも注意してください。0.2 では env セクションの variables 記述方法が変わります。


演習3: appspec.yml — Hooks 順序ミス + ValidateService timeout漏れ (YAML)

CodeDeploy の appspec.yml は Hooks の実行順序が固定されており、
ValidateServicetimeout を設定しないとデフォルト 3600秒待ち続けます。

■ Before (アンチパターン)

version: 0.0
os: linux
files:
  - source: /
 destination: /var/www/myapp

hooks:
  ApplicationStart: # 先にアプリを起動しようとしている (順序ミス)
 - location: scripts/start_app.sh
timeout: 30
  BeforeInstall: # 後から依存ライブラリをインストール (逆順)
 - location: scripts/install_deps.sh
timeout: 60
  ValidateService:
 - location: scripts/validate.sh
# timeout 未設定 → デフォルト 3600秒待ち

■ After (正解パターン)

version: 0.0
os: linux
files:
  - source: /
 destination: /var/www/myapp

hooks:
  BeforeInstall:
 - location: scripts/install_deps.sh
timeout: 60
  AfterInstall:
 - location: scripts/configure_app.sh
timeout: 30
  ApplicationStart:
 - location: scripts/start_app.sh
timeout: 30
  ValidateService:
 - location: scripts/validate.sh
timeout: 60# 明示推奨: 30〜120秒

解説:
EC2/On-Premises のライフサイクルは BeforeInstall → AfterInstall → ApplicationStart → ValidateService の順序です。
BeforeInstall でファイル配置前の依存関係インストール・旧プロセス停止を行い、
AfterInstall で設定ファイル反映、ApplicationStart でプロセス起動、ValidateService でヘルスチェックを実施します。
ValidateServicetimeout 省略時は 3600秒に設定されるため、検証スクリプトがハングすると 1時間待ち続ける事態になります。


演習4: GitHub Actions OIDC Trust Policy — sub claim ワイルドカード全許可 (YAML)

IAM Trust Policy の sub claim を refs/heads/* で許可すると、
任意のブランチから本番 AWS ロールを assume できてしまいます。

■ Before (アンチパターン)

# IAM Trust Policy (aws_iam_role の assume_role_policy)
Version: "2012-10-17"
Statement:
  - Effect: Allow
 Principal:
Federated: "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
 Action: "sts:AssumeRoleWithWebIdentity"
 Condition:
StringLike:  # ワイルドカード許可
  "token.actions.githubusercontent.com:sub":
 "repo:myorg/myrepo:ref:refs/heads/*"
StringEquals:
  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"

■ After (正解パターン)

# IAM Trust Policy — main ブランチのみに限定
Version: "2012-10-17"
Statement:
  - Effect: Allow
 Principal:
Federated: "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
 Action: "sts:AssumeRoleWithWebIdentity"
 Condition:
StringEquals:# 完全一致に変更
  "token.actions.githubusercontent.com:sub":
 "repo:myorg/myrepo:ref:refs/heads/main"
  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"

解説:
StringLike + refs/heads/* は「任意のブランチ」からの assume を許可します。
feature/evil-branch のようなブランチを作成されると、そのブランチから本番 AWS リソースへのアクセスが可能になります。
StringEquals + refs/heads/main に限定することで、main マージ済みコードのみが本番 IAM ロールを assume できます。
ステージング環境用には別ロールを作成し refs/heads/develop に限定する設計が推奨です。
Pull Request からのデプロイを許可する場合は refs/pull/*/merge を別ロールとして用意してください。


演習5: CodeDeploy Auto Rollback — Alarm 閾値が緩すぎて検知漏れ (Terraform)

Auto Rollback の CloudWatch Alarm 閾値を 50 (エラーレート 50%) に設定すると、
エラーが多発してもロールバックが発動せず被害が拡大します。

■ Before (アンチパターン)

resource "aws_cloudwatch_metric_alarm" "error_rate" {
  alarm_name = "my-app-error-rate"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name= "5XXError"
  namespace  = "AWS/ApplicationELB"
  period  = 60
  statistic  = "Average"
  threshold  = 50 # 50% エラーレートでようやく検知 (遅すぎる)
  alarm_description= "Error rate alarm for CodeDeploy rollback"

  dimensions = {
 LoadBalancer = aws_lb.main.arn_suffix
  }
}

resource "aws_codedeploy_deployment_group" "main" {
  app_name= aws_codedeploy_app.main.name
  deployment_group_name  = "production"
  service_role_arn = aws_iam_role.codedeploy.arn

  auto_rollback_configuration {
 enabled = true
 events  = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
  }

  alarm_configuration {
 alarms  = [aws_cloudwatch_metric_alarm.error_rate.alarm_name]
 enabled = true
  }
}

■ After (正解パターン)

resource "aws_cloudwatch_metric_alarm" "error_rate" {
  alarm_name = "my-app-error-rate"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 2# 連続2期間で閾値超えを確認 (誤検知防止)
  metric_name= "5XXError"
  namespace  = "AWS/ApplicationELB"
  period  = 60
  statistic  = "Average"
  threshold  = 5# 5% エラーレートで即検知
  treat_missing_data  = "notBreaching"
  alarm_description= "Error rate alarm for CodeDeploy auto rollback"

  dimensions = {
 LoadBalancer = aws_lb.main.arn_suffix
  }
}

resource "aws_codedeploy_deployment_group" "main" {
  app_name= aws_codedeploy_app.main.name
  deployment_group_name  = "production"
  service_role_arn = aws_iam_role.codedeploy.arn

  auto_rollback_configuration {
 enabled = true
 events  = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
  }

  alarm_configuration {
 alarms  = [aws_cloudwatch_metric_alarm.error_rate.alarm_name]
 enabled = true
 ignore_poll_alarm_failure = false
  }
}

解説:
threshold = 50 ではエラーレートが 50% 以上にならないとアラームが発火しません。
本番トラフィックの半数がエラーになって初めて検知される設計は、SLA や UX の観点から許容できません。
threshold = 5 (5% エラーレート) + evaluation_periods = 2 が本番運用の目安です。
treat_missing_data = "notBreaching" を設定することで、デプロイ直後のメトリクス欠損期間に誤ってアラームが発火するのを防げます。
ignore_poll_alarm_failure = false で Alarm 状態の取得失敗時にも安全側 (ロールバック実行) に倒します。


8. まとめ + Vol2予告 + 落とし穴10選 + 全9軸クロスリンク + 第10軸完結宣言

本節では Vol1 の学習内容を整理し、よくある落とし穴と次のステップを示します。

Vol1 の振り返り

DevOps 3本柱と AWS の 4 主要ツールの対応を再確認します。

本柱AWS ツールVol1 のポイント
ビルド自動化CodeBuildbuildspec.yml v0.2 設計・Secrets Manager 連携・cache 最適化
テスト自動化CodeBuild Reports / GitHub Actionsjunit レポート統合・マルチアーキ対応
デプロイ自動化CodeDeployBlue/Green 切替・appspec.yml Hooks・Auto Rollback
オーケストレーションCodePipeline / GitHub Actionsステージ設計・Artifacts 管理・手動承認・EventBridge 通知

全9軸 (IAM × EKS × 復旧 × AI × セキュリティ × コスト × マルチアカウント × Observability × Network) で培った知識は、
CodePipeline のパイプラインを通じて自動的に本番環境へ届けられます。
第10軸 = DevOps/CI/CD実践 は、全9軸の知識をコードとして本番に運ぶ自動化基盤です。


落とし穴10選

CI/CD 構築で実際によく踏まれる落とし穴をまとめます。

  1. Artifact Bucket KMS暗号化漏れ — Deploy ロールに kms:Decrypt がなく Deploy ステージで失敗
  2. 手動承認 SNS通知未設定 — 承認待ち状態のまま Pipeline が止まり誰にも気付かれない
  3. buildspec.yml v0.1/v0.2 混在env.variables 構造の違いで環境変数が注入されない
  4. Pipeline Service Role に AdministratorAccess — 最小権限違反。Source/Build/Deploy ロールは分離する
  5. Blue/Green Hook ValidateService timeout 漏れ — デフォルト 3600秒待ちでデプロイが 1時間停止
  6. OIDC sub claim refs/heads/* 全許可 — 任意ブランチから本番 AWS ロールを assume 可能になる
  7. Auto Rollback Alarm 閾値が緩すぎthreshold = 50 ではエラー多発を検知できない
  8. CodeBuild VPC接続で NAT GW コスト増大 — Private Subnet 内 CodeBuild は NAT GW 経由になり料金が急増
  9. Cross-Region Artifact KMS未設定 — マルチリージョン Pipeline でリージョン間 Artifact が暗号化されない
  10. CodeDeploy Lambda Canary 重み付け誤設定 — Traffic Shifting の割合設定ミスで 100% 切替が遅延

Vol2 — Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting

Vol2 では Vol1 の4本柱 (CodePipeline/CodeBuild/CodeDeploy/GitHub Actions) を基盤として、デプロイ対象別の深化を扱います。

  • Container CD: ECR + ECS Blue/Green + EKS GitOps (Argo CD / Flux)
  • CodeArtifact: npm / Maven / PyPI プライベートリポジトリ + buildspec.yml 統合
  • SAM Pipeline: Lambda マルチアカウントデプロイ + Alias Traffic Shifting
  • Amplify Hosting: SPA/SSG Branch deploy + Preview deploy + Custom Domain

DevOps/CI/CD実践 Vol2: Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting → 読む


AWS本番運用 全9軸シリーズ (20記事) + 第10軸 DevOps/CI/CD実践
本記事は全9軸シリーズ (20記事) のハブ記事として、各軸の本番運用知識を CI/CD 自動化基盤に接続します。

第1軸: IAM (4記事)
IAM ポリシー設計入門 Vol1 / IAM マルチアカウント設計 Vol2 / IAM Permissions Boundary Vol3 / IAM STS クロスアカウント Vol4

第2軸: EKS (3記事)
EKS 本番基盤構築 Vol1 / EKS CI/CD 実践 Vol2 / EKS 本番 Observability Vol3

第3軸: 復旧 (4記事)
DR 基礎設計 Vol1 / DR マルチリージョン Vol2 / DR マルチリージョン Active 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 ハイブリッドネットワーク (Direct Connect/VPN/Transit Gateway) Vol2

第10軸: DevOps/CI/CD実践 (本シリーズ)
Vol1 (本記事): CodePipeline × CodeBuild × CodeDeploy × GitHub Actions OIDC
Vol2: Container CD × CodeArtifact × SAM Pipeline × Amplify Hosting

第11軸: Database本番運用 (1記事)
Database本番運用入門 Vol1 — RDS × Aurora × DynamoDB


第10軸 DevOps/CI/CD実践シリーズ — Vol1 完結

本記事では、全9軸シリーズで培った AWS 本番運用知識を自動化基盤として運ぶための
DevOps/CI/CD 実践入門 Vol1 を完走しました。

CodePipeline のステージ設計から CodeBuild の buildspec 設計、
CodeDeploy の Blue/Green 実装、GitHub Actions OIDC 連携、そして 5問の演習まで、
第10軸シリーズの起点として必要な知識を一冊に網羅しています。

Vol2 の Container CD / CodeArtifact / SAM Pipeline / Amplify Hosting で、さらに深い自動化基盤を構築しましょう。