Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS CDK用のCI/CD構築 ~大規模案件における実装時の工夫3選~

Avatar for 渡洸貴 渡洸貴
January 28, 2026
480

AWS CDK用のCI/CD構築 ~大規模案件における実装時の工夫3選~

Avatar for 渡洸貴

渡洸貴

January 28, 2026
Tweet

Transcript

  1. 目次 1. 自己紹介 2. IaCとは 3. CDKとは 4. テーマ概要 5.

    パイプラインの構造 6. 工夫点①~③ 7. まとめ
  2. 自己紹介 入社年 渡 洸貴 わたり こうき 2023年入社(3年目) 業務内容 公共部門の技術集約組織における、 ガバメントクラウドでのシステム開発の生産性向上

    施策チームに所属。 分野横断で活用できるアセットの整備や、それを 活用してガバメントクラウド開発案件への支援を 行っている。 3
  3. Infrastructure as Code(IaC)とは? 手動のプロセスや設定の代わりにコードを使用してインフラストラクチャの管理やプロビジョニングを行う手法。 IaCのメリットとして、コスト削減、スピードアップ、リスク低減がある。 AWS Cloud リソースを コードで定義 IaCツール

    数分で目的の環境が用意可能 IaCのメリット ◼ コスト削減 ・ 手順書の作成、メンテナンス、引継ぎコストを削減 ・ 手順書と実環境の乖離によるブラックボックス化を防⽌ ・ デプロイ作業時間を削減 ・ 必要なときにリソースを作成、まとめて破棄 ◼ スピードアップ ・ CI/CD で自動テスト、デプロイ ・ 変更を予測可能にして頻繁にデプロイ ・ 同じ構成を何度でもデプロイ ・ 構成パターンとベストプラクティスの共有 ◼ リスク低減 ・ ⼈的ミスの排除 ・ バージョン管理による変更の追跡と承認プロセス ・ 信頼できる唯⼀の情報源としての Git リポジトリ ・ 必要に応じて前のバージョンにロールバック 4
  4. パイプラインのアーキテクチャを以下に示す。以下3つのステージで構成される。 1. ソースステージ CodeCommitの指定したリポジトリ、ブランチにPushされるとパイプラインが実行。 2. ビルドステージ CodeBuildを使用してスタックの変更セットを作成。 3. デプロイステージ 承認アクション:SNSを介して承認依頼通知を行い実行を⼀時停⽌。

    デプロイアクション:手動承認後に変更セットを環境にデプロイ。 ※このパイプライン自体もCDKで実装している パイプラインの構造 CICD環境アカウント 本番環境アカウント CodePipeline (prd用) prdブランチ pushで起動 Deploy Stage(入力条件を設定) SNS Build Stage BuildProject サービスロール Build Action Build Action N Approval Action Approval Action N Deploy Action N Deploy Action Deploy Stage N Build Stage N CDK Deploy Set CDK Deploy Set N ・・・ ・・・ ・・・ Source Stage Build Action Deploy+ Approval Action ・・・ ・・・ Build Action N Deploy+ Approval Action ExecuteChangeset cdk-bootstrap-role (deploy-role) CloudFormation Code Commit Gitコミット CDK App Pipelie サービスロール Assume Assume Commands Action Commands Action 7
  5. 工夫点① どんな構造のCDKアプリケーションであっても共通的に使用できるCI/CDパイプラインを用意したい。 1App複数Stackの構造をとっている場合に、1度のパイプライン実行で全Stackに対応できる必要がある。 さらに、Stack間で依存関係がある場合はデプロイ順序に制約があることも。 my_app/ ├ bin/ │└ my_app.ts ├

    lib/ │ ├ MyStack.ts ・ ・ ・ CICD環境アカウント CodePipeline Deploy Stage SNS Build Stage Build Action Approval Action Deploy Action CDK Deploy Set Source Stage ExecuteChangeset Code Commit my_app/ ├ bin/ │└ my_app.ts ├ lib/ │ ├ PreStack1.ts │ ├ PreStack2.ts │ └ PostStack.ts ・ ・ ・ 1App1Stackにのみ対応したパイプライン 8 CodeBuild
  6. 1App複数Stackに対応するため、CDK内のスタック数および順序関係に応じてステージ数を変更可能 スタックのデプロイ順序関係がない場合はステージ内でアクションを追加し、順序関係がある場合はステージ自体を追加する。 工夫点① CICD環境アカウント CodePipeline (prd用) Deploy Stage 2(入力条件を設定) SNS

    Build Stage 1 <PreStack1> Build Action <PreStack1> Approval Action <PreStack1> Deploy Action CDK Deploy Set1(PreStack用) Source Stage ExecuteChangeset Code Commit CodeBuild Deploy Stage 2(入力条件を設定) SNS Build Stage 2 <PostStack> Build Action <PostStack> Approval Action <PostStack> Deploy Action CDK Deploy Set2(PostStack用) ExecuteChangeset CodeBuild 「PreStack1」と「PreStack2」は 順序関係がないため、同⼀ステージ 内で並列に作成 SNS <PreStack2> Build Action <PreStack2> Approval Action <PreStack2> Deploy Action ExecuteChangeset CodeBuild 「PostStack」は「PreStack」と依 存関係があるため、別ステージとし て直列に作成 Commands Action Commands Action (例)1つのCDKアプリケーション内に以下3つのStackが含まれる場合 ▪ PreStack1、PreStack2(PreStack間は順序関係なし) ▪ PostStack(PreStackの後にデプロイが必要) 9
  7. 工夫点① パイプラインを作成するCDKコード側で、設定ファイルを書き換えるだけで簡単にステージ数を増減できるような構造とした。 interface PipelineProps { pipelineConfigs: { pipelineName: string; stacksConfigs:

    { [buildStageIdentifier: string]: { stackName: string; }[]; } }[]; } ~~~~~~~~~~~~~~~~~~~ // ─────────────────────────────── // for① パイプライン数 // ─────────────────────────────── for (const pipelineConfig of props.pipelineConfigs) { // パイプライン、ソースステージ等を定義 const myPipeline = ・・・; // ───────────────────────────── // for② ステージ数(垂直スケール) // ───────────────────────────── for (const buildStageIdentifier of Object.keys(pipelineConfig.stacksConfigs)) { // ─────────────────────────── // for③ ステージ内アクション数(水平スケール) // ─────────────────────────── const stacksConfigs = pipelineConfig.stacksConfigs[buildStageIdentifier]; for (const stacksConfig of stacksConfigs) { // 設定ファイルの内容に応じてビルドステージやデプロイステージを定義 const myBuildAction = ・・・; const myDeployAction = ・・・; } } } export const PipelineProps = [ { pipelineName: "cdk-app1", stacksConfigs: { common: [ { stackName: "commonStackA", region: "ap-northeast-1" }, { stackName: "commonStackB", region: "ap-northeast-3" }, ], } }, { pipelineName: "cdk-app2", stacksConfigs: { db: [ { stackName: "dbStack", region: "ap-northeast-1" } ], app: [ { stackName: "appStack", region: "ap-northeast-1" } ] } } ] 【設定コード】 【リソースコード】 水平スケール 依存関係がないStack用 垂直スケール 依存関係があるStack用 for文で処理することで 設定ファイルに応じて パイプライン数、ステージ数、 アクション数を可変にする 10
  8. 工夫点② CDKアプリケーションが1App複数Stackの場合に、変更を加えた1つのStackのみ更新をかけたいケースが存在する。 パイプラインが実行されることで全Stackに更新が走ってしまうと、変更がないStackに対して承認通知やデプロイが走ってしまうこ とが懸念される。 my_app/ ├ bin/ │└ my_app.ts ├

    lib/ │ ├ PreStack1.ts │ ├ PreStack2.ts │ └ PostStack.ts ・ ・ ・ PostStackにだけ変更を加えたのに、 PreStack1やPreStack2までデプロイ 承認通知が届く。。 変更を加えたコード CodePipeline SNS ExecuteChangeset Code Commit CodeBuild Source Stage Deploy Stage 1 Build Stage 1 CodeBuild SNS ExecuteChangeset Deploy Stage 2 Build Stage 2 SNS ExecuteChangeset CodeBuild ×3 11
  9. ビルドステージにてスタック変更差分がない場合にデプロイステージをスキップするよう「入力条件」を設定 • スタック変更差分は各スタックのビルドステージで”cdk diff”コマンドで確認し、確認結果を環境変数に格納する。 • Commands Actionでは前段の各スタックの差分有無結果を確認し、デプロイステージのスキップ判別用フラグを環境変数に 格納する。各スタックのうち1つでも差分があれば「”yes”」を格納し、1つも差分が無ければ「”no”」を格納する。 • その環境変数の値に応じてデプロイステージをスキップする。

    工夫点② CICD環境アカウント CodePipeline (prd用) Deploy Stage(入力条件を設定) Build Stage Deploy Stage N Build Stage N CDK Deploy Set CDK Deploy Set N ・・・ Source Stage Build Action Deploy+ Approval Action CodeCommit ③「RESULT」の値を参照し、 「”yes”」:ステージを実行 「”no”」:ステージをスキップ Commands Action 環境変数: CommandsVariables.RESULT ②「CDK_DIFF_RESULT」が 1つでも”yes”がある:「RESULT」に「”yes”」を格納 全て”no”:「RESULT」に「”no”」を格納 Commands Action 環境変数: BuildVariables.CDK_DIFF_RESULT Build Action BuildProject サービスロール CodeBuild Approval Action Deploy Action SNS ExecuteChangeset ①各Stackのビルドで“cdk diff”を実行し、 差分有無(”yes” or “no”)を環境変数 「CDK_DIFF_RESULT」に格納。 Build Actionは 並列実行 ※cdk diffとは 「ローカルCDKコードの合成結果」と 「デプロイ済みのCfn Stack」 の差分を確認するコマンド 12
  10. 承認アクションでは、スタック変更差分(”cdk diff”実行結果)を確認して承認を行うことが可能 • 変更差分はビルドステージで作成してアーティファクトバケットに格納し、S3の「署名付きURL」を発行する。 • 承認依頼のSNSで、通知本文に「レビュー用リンク」として「署名付きURL」を設定する。 工夫点③ CICD環境アカウント CodePipeline (prd用)

    Deploy Stage(入力条件を設定) SNS Build Stage BuildProject サービスロール Build Action Approval Action Deploy Action Deploy Stage N Build Stage N CDK Deploy Set CDK Deploy Set N ・・・ Source Stage Build Action Deploy+ Approval Action ExecuteChangeset アーティファクトバケット CodeCommit CodeBuild cdk-diff.html 環境変数: BuildVariables.CDK_DIFF_URL 署名付きURL: https://xxxx.s3.ap-northeast-1.amazonaws.com/~ ① “cdk diff”結果を取得し、 HTMLファイルとして S3にアップロード ② 署名付きURLを発行して、 「CDK_DIFF_URL」に格納する。 接続元の IPアドレス制限を設定 Sub: APPROVAL_NEEDED: ~ ... Content to review: https://xxx.s3.ap-northeast- 1.amazon.com/~(署名付きURL) ... 承認依頼 通知 レビュー用リンク: #{BuildVariables.CD K_DIFF_URL} 変数の参照 ③ 「署名付きURL」を記載した 承認依頼を通知 Teams等 ④ 通知内のリンクを押下し、 変更内容をブラウザで確認する。 Commands Action ※署名付きURLとは S3オブジェクトをダウンロードするアクセス許可を期限付きで付与。 認証情報はURLを生成したIAMユーザーのものを使用。 14
  11. まとめ CDKをデプロイするCI/CDパイプラインの構成を紹介。 工夫した点は以下3点。 ① CDK内のスタック数および順序関係に応じてステージ数を変更 → 1App複数Stackに対応 ② スタック変更差分がない場合にデプロイステージをスキップ →

    無駄な通知が来ない ③ スタック変更差分を承認通知に含める → 承認者が変更を理解して承認可能 CDKによるインフラ構築を実施されている方は是非参考にしてみてください! CICD環境アカウント 本番環境アカウント CodePipeline (prd用) prdブランチ pushで起動 Deploy Stage(入力条件を設定) SNS Build Stage BuildProject サービスロール Build Action Build Action N Approval Action Approval Action N Deploy Action N Deploy Action Deploy Stage N Build Stage N CDK Deploy Set CDK Deploy Set N ・・・ ・・・ ・・・ Source Stage Build Action Deploy+ Approval Action ・・・ ・・・ Build Action N Deploy+ Approval Action ExecuteChangeset cdk-bootstrap-role (deploy-role) CloudFormation Code Commit Gitコミット CDK App Pipelie サービスロール Assume Assume Commands Action Commands Action 15