CDK Pipelines のサンプル "aws-samples/cdk-pipelines-demo" が実際にどのような構成を作っているのか調べる
参照しているのはこちら
残念ながら CDK v1 時代のソースなのでさほど参考にはならないかもしれないが、pipelines がどういうものを作ろうとしているのかがなんとなく把握できれば良しとする
cdk synth
で出力した内容のうち、CodePipeline で何するかをうっすら見ていく。IAM Role なんかは気にしずデプロイするまでに必要な本質的な処理の把握に絞る
CodePipeline ステージ構成
6 つのステージからなる。論理リソースID はひとまずそのままコピペ
なんとなくこのまとめを見れば各ステージで何しようとしているのかはわかる
(1) Stage = GitHub
GitHub source action
Output = Artifact_Source_GitHub
(2) Stage = Build
CodeBuild "PipelineBuildSynthCdkBuildProject6BEFA8E6"
Output = Artifact_Build_Synth
(3) Stage = UpdatePipeline
CodeBuild "PipelineUpdatePipelineSelfMutationDAA41400"
SelfMutation
とあるように、このパイプライン自身の変更を実行しようとしているように見える。
この SelfMutation
というコンセプト自体は v2 の pipelines にも存在するので把握しといてOK。
(4) Stage = Assets
CodeBuild "PipelineAssetsFileAsset185A67CB4"
(5) Stage = Pre-Prod
(5-1) WebService.Prepare (runOrder=1)
CloudFormation deploy "Pre-Prod-WebService"
ActionMode = CHANGE_SET_REPLACE
(5-2) WebService.Deploy (runOrder=2)
CloudFormation deploy "Pre-Prod-WebService"
ActionMode = CHANGE_SET_EXECUTE
(5-3) IntegrationTests (runOrder=3)
CodeBuild "PipelinePreProdIntegrationTestsProject84C5132E"
(6) Stage = Prod
(6-1) WebService.Prepare (runOrder=1)
CloudFormation deploy "Prod-WebService"
ActionMode = CHANGE_SET_REPLACE
(6-2) WebService.Deploy
CloudFormation deploy "Prod-WebService"
ActionMode = CHANGE_SET_EXECUTE
pipeline の実装は以下のようなノリ
const synthAction = pipelines.SimpleSynthAction.standardNpmSynth({
sourceArtifact,
cloudAssemblyArtifact,
buildCommand: 'npm run build && npm test',
});
const pipeline = new pipelines.CdkPipeline(this, 'Pipeline', {
cloudAssemblyArtifact,
sourceAction,
synthAction
});
// Pre-prod
//
const preProdApp = new WebServiceStage(this, 'Pre-Prod');
const preProdStage = pipeline.addApplicationStage(preProdApp);
preProdStage.addActions(...)
// Prod
//
const prodApp = new WebServiceStage(this, 'Prod');
const prodStage = pipeline.addApplicationStage(prodApp);
CodePipeline のステージとしては SelfMutation を行うステージが最初に来て、その後 addStage すると後ろに「私がパイプライン越しにデプロイしたいと思っている IaC テンプレのデプロイ」を行うステージが繋がる感じに見える。
(2) Stage = Build
CodeBuild "PipelineBuildSynthCdkBuildProject6BEFA8E6"
Output = Artifact_Build_Synth
対応してる実装はこれ
const synthAction = pipelines.SimpleSynthAction.standardNpmSynth({
sourceArtifact,
cloudAssemblyArtifact,
buildCommand: 'npm run build && npm test',
});
生成された CloudFormation に書いてある PipelineBuildSynthCdkBuildProject6BEFA8E6
の BuildSpec はこれ↓
cdk synth する手前のコマンドにカスタマイズの余地があるっぽい。
{
"version": "0.2",
"phases": {
"pre_build": {
"commands": [
"npm ci"
]
},
"build": {
"commands": [
"npm run build && npm test",
"npx cdk synth"
]
}
},
"artifacts": {
"base-directory": "cdk.out",
"files": "**/*"
}
}
(3) Stage = UpdatePipeline
CodeBuild "PipelineUpdatePipelineSelfMutationDAA41400"
SelfMutation はデフォルトの振る舞いで自動生成される系のリソースなので CDK コード中に明示的にこれを生成している部分はない(はず)
自動生成された CodeBuild PipelineUpdatePipelineSelfMutationDAA41400
の BuildSpec はこれ↓
{
"version": "0.2",
"phases": {
"install": {
"commands": "npm install -g aws-cdk"
},
"build": {
"commands": [
"cdk -a . deploy PipelineStack --require-approval=never --verbose"
]
}
}
}
PipelineStack
はサンプルコードで定義してる最上位の Stack 要素。
ここに含まれてるのはパイプラインのスタックで、プロダクトコードに相当する部分の Stack は含んでいない(これを自分は少し混同していた)
(4) Stage = Assets
CodeBuild "PipelineAssetsFileAsset185A67CB4"
PipelineAssetsFileAsset185A67CB4
の BuildSpec は以下。
{
"version": "0.2",
"phases": {
"install": {
"commands": "npm install -g cdk-assets"
},
"build": {
"commands": [
"cdk-assets --path \"assembly-PipelineStack-Pre-Prod/PipelineStackPreProdWebService366DDB3C.assets.json\" --verbose publish \"d13603a1f070cfad016ec67b8286a6e0043af96b03f4c43d8575400184acb608:current_account-current_region\"",
"cdk-assets --path \"assembly-PipelineStack-Prod/PipelineStackProdWebServiceFF6D621D.assets.json\" --verbose publish \"d13603a1f070cfad016ec67b8286a6e0043af96b03f4c43d8575400184acb608:current_account-current_region\""
]
}
}
}
cdk-assets
というコマンドがあるのは初めて知った。CDK の本体レポジトリにあるらしい。
A tool for publishing CDK assets to AWS environments.
と説明文にある通り、デプロイ対象のアカウントにアセットをアップロードするツールに見える。
synth した後生成されている Cloud Assembly をインプットとするコマンドらしいが、いったん理解を棚上げして先に進むことにする。
cdk-assets requires an asset manifest file called assets.json, in a CDK CloudAssembly (cdk.out/assets.json). It will take the assets listed in the manifest, prepare them as required and upload them to the locations indicated in the manifest.
5,6 は共通していて、このへんは CodePipeline で Cfn Provider のアクションを実行するもの。
ActionMode
という概念が出てくるが、だいたい見ればニュアンスは把握できるので省略する。
それぞれのステージも名前を見ればおおよそやってることの想像はつくので省略。
ActionMode の仕様は以下のドキュメントを参照
(5) Stage = Pre-Prod
(5-1) WebService.Prepare (runOrder=1)
CloudFormation deploy "Pre-Prod-WebService"
ActionMode = CHANGE_SET_REPLACE
(5-2) WebService.Deploy (runOrder=2)
CloudFormation deploy "Pre-Prod-WebService"
ActionMode = CHANGE_SET_EXECUTE
(5-3) IntegrationTests (runOrder=3)
CodeBuild "PipelinePreProdIntegrationTestsProject84C5132E"
PipelinePreProdIntegrationTestsProject84C5132E
の BuildSpec は以下。
{
"version": "0.2",
"phases": {
"build": {
"commands": [
"set -eu",
"export SERVICE_URL=\"$(node -pe 'require(process.env.CODEBUILD_SRC_DIR_Artifact_PipelineStackPreProdWebService366DDB3C_Outputs + \"/outputs.json\")[\"url\"]')\"",
"npm install",
"npm run build",
"npm run integration"
]
}
}
}
対応する PreProd のステージ実装は以下。
// Pre-prod
//
const preProdApp = new WebServiceStage(this, 'Pre-Prod');
const preProdStage = pipeline.addApplicationStage(preProdApp);
const serviceUrl = pipeline.stackOutput(preProdApp.urlOutput);
preProdStage.addActions(new pipelines.ShellScriptAction({
actionName: 'IntegrationTests',
runOrder: preProdStage.nextSequentialRunOrder(),
additionalArtifacts: [
sourceArtifact
],
commands: [
'npm install',
'npm run build',
'npm run integration'
],
useOutputs: {
SERVICE_URL: serviceUrl
}
}));
npm scripts に npm run integration
対応する実装は書いてある。このサンプルでは雛形のみで実際に意味のある処理はしていない様子だったが、API Gateway のエンドポイントを実際に叩いてレスポンスを確かめるようなものを意図している様子だった。
(6) Stage = Prod
(6-1) WebService.Prepare (runOrder=1)
CloudFormation deploy "Prod-WebService"
ActionMode = CHANGE_SET_REPLACE
(6-2) WebService.Deploy
CloudFormation deploy "Prod-WebService"
ActionMode = CHANGE_SET_EXECUTE
全体的なパイプラインの流れを図示するとこんな感じになった。