はじめに
ほうき星です。
SAM(Serverless Application Model)のCI/CDを構築しているとき、ふとこう思ったことはありませんか?
「
sam deployで即スタック更新されるのちょっと怖い...」
私も「スタックへの変更内容を確認せずに反映されるの怖い...」と思ってました。
なので
-
sam deployで変更セットだけ作って - 内容を確認してから
- 手動承認後に適用される
そんな“安心・安全なデプロイ”を実現したくて、CodePipelineを使った構成を試してみました。
本記事では、そんな「確認ステップを挟んだ安全なデプロイフロー」を CodePipeline 上で実現する方法をご紹介します。
この記事で構築するCI/CDパイプラインの構成
今回はCodePipelineを使用して、次のようなステージ構成のパイプラインを構築します。
- ソースステージ
リポジトリをトリガーとして、ソースコードを取得 - ビルド&変更セット作成ステージ
sam deploy --no-execute-changesetでCloudFormationの変更セットのみ作成 - 手動承認ステージ
手動承認アクションで変更セットに問題がないかを確認 - 変更セット適用ステージ
CloudFormationの変更セット実行アクションでデプロイ
実装サンプル
本記事にはキモとなる部分だけ記載してます。
CI/CDのSAMテンプレートを含む全ソースは下記リポジトリに置いていますので、参考にしてください。
buildspec.ymlの例(ビルド&変更セット作成ステージ)
Build&変更セットステージではCodeBuildを使用してsam buildとsam deployを実施します。
sam deployでは--no-execute-changesetオプションをつけており、変更セットの実行までは行いません。
またCodeBuildの出力変数として変更セット名をChangeSetName、変更セットの差分確認画面のURLをChangeSetURLを後続ステージへ渡しています。
version: 0.2
env:
exported-variables:
- ChangeSetName
- ChangeSetURL
phases:
install:
runtime-versions:
python: 3.12
build:
commands:
- echo "[INFO] Building the SAM application"
- sam build
- echo "[INFO] Building completed"
post_build:
commands:
- echo "[INFO] Creating new ChangeSet of $STACK_NAME"
- output=$(sam deploy --stack-name $STACK_NAME --no-execute-changeset --role-arn $ROLE_ARN --s3-bucket $SAM_CLI_SOURCE_BUCKET)
# 変更セット名を出力
- export ChangeSetName=$(echo "$output" | sed -n 's#.*/\(samcli-deploy[0-9]*\)/.*#\1#p')
- stack_id=$(aws cloudformation describe-stacks --stack-name $STACK_NAME --query "Stacks[0].StackId" --output text)
- change_set_id=$(aws cloudformation describe-change-set --stack-name $STACK_NAME --change-set-name "$ChangeSetName" --query "ChangeSetId" --output text)
# 変更セットのURLを出力
- export ChangeSetURL="https://$AWS_DEFAULT_REGION.console.aws.amazon.com/cloudformation/home?region=$AWS_DEFAULT_REGION#/stacks/changesets/changes?stackId=$stack_id&changeSetId=$change_set_id"
- echo "[INFO] Creating new ChangeSet of $STACK_NAME completed"
手動承認ステージ
手動承認ステージではビルド&変更セット作成ステージにて出力されたChangeSetURLをExternalEntityLinkプロパティに設定し、手動承認実施時に変更セットの差分確認ページに飛ぶことができるようにしています。
- Name: "ManualApprovalStage" # 手動承認ステージ
Actions:
- Name: "ApprovalDeploy"
ActionTypeId:
Category: "Approval"
Owner: "AWS"
Version: "1"
Provider: "Manual"
Configuration:
ExternalEntityLink: "#{BuildNamespace.ChangeSetURL}"
CustomData: "レビュー用 URLからスタックの変更セットの内容を確認し、問題なければ承認してください"
変更セット適用ステージ
ビルド&変更セット作成ステージにて作成された変更セットは、手動承認ステージでの承認を経てCloudFormationのデプロイアクションCHANGE_SET_EXECUTEで適用されます。
- Name: "DeployChangeSetStage" # 変更セット適用ステージ
Actions:
- Name: "Deploy"
ActionTypeId:
Category: "Deploy"
Owner: "AWS"
Provider: "CloudFormation"
Version: "1"
Configuration:
ActionMode: "CHANGE_SET_EXECUTE"
StackName: !Ref "SAMStackName"
ChangeSetName: "#{BuildNamespace.ChangeSetName}"
さいごに
本記事ではsam deploy時に--no-execute-changesetオプションを使用し変更セットの作成のみを行い、手動承認時に変更箇所を確認し、承認後変更セットを適用するようなCI/CDパイプラインを紹介しました。
この構成が誰かの役に立てば幸いです。

