こんにちは、ちゃりおです。
CDK Pipelineをざっくり試したいと思っていて、なにかいいチュートリアルないかと探していたら。「AWS CDK ADVANCED WORKSHOP」なるものを発見しました。
CDK Pipelineやパッケージ化を自分で手を動かして学ぶのによい教材だったので紹介します。
ワークショップの概要
- マルチリージョン構成の作成
- カスタムリソースの使用
- L1を使ったリソースの更新
- CDKコンストラクトのパッケージ化
- CDKパイプラインを使用したデプロイ
必要な時間: 2~3時間
Create Our Sample Application
作成するリソースはこんな感じです。
Source BucketとTarget BucketではS3のレプリケーションが行われています。
Regionで作成するリソースごとにConstructが分かれています。
「us-east-1」で作成したKMSのキーを「us-east-2」で使用する
2つのリージョンに配置するS3はレプリケーションしています。
レプリケーションのために、source側(us-east-1)でtarget側(us-east-2)のS3のKMSキーを取得可能な必要があります。
このハンズオンでは取得するために以下を行っています。
- target側: パラメーターストアを作成・KMSのキーARNをパラメーターストアに保存
- source側: Custom Resourceを使用して別リージョンのパラメーターストアからKMSキーARN取得
該当部分を抜き出しました。
# multi-region-s3-crr-kms-cmk-target/lib/index.ts
new ssm.StringParameter(this, 'MyTargetKeyIdSSMParam', {
parameterName: parameterName,
description: 'The KMS Key Id for the target stack',
stringValue: targetKmsKey.keyArn
});
this.targetBucket = targetBucket;
this.targetKeyIdSsmParameterName = parameterName;
# multi-region-s3-crr-kms-cmk-source/lib/index.ts
const stack = cdk.Stack.of(this);
const parameterArn = stack.formatArn({
account: stack.account,
region: props.targetRegion,
resource: 'parameter',
resourceName: props.targetKeyIdSsmParameterName,
service: 'ssm'
});
const targetKeyLookupCR = new cr.AwsCustomResource(this, 'TargetKeyLookup', {
onUpdate: { // will also be called for a CREATE event
service: 'SSM',
action: 'getParameter',
parameters: {
Name: props.targetKeyIdSsmParameterName
},
region: props.targetRegion,
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString())
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({resources: [parameterArn]})
});
パッケージ化したConstructを使用する
targetとsourceのコンストラクトをパッケージ化して使用します。
jsiiを使用してそれぞれパッケージ化しました。
AWS CDK Advanced Workshop > Create Our Sample Application > Replication Target Construct > jsii and package.json
パッケージ使用する側のコードはこんな感じです。だいぶスッキリしましたね。
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { MultiRegionS3CrrKmsCmkSourceStack } from '../lib/multi-region-s3-crr-kms-cmk-source-stack';
import { MultiRegionS3CrrKmsCmkTargetStack } from '../lib/multi-region-s3-crr-kms-cmk-target-stack';
const accountId = '';
const app = new cdk.App();
const targetStack = new MultiRegionS3CrrKmsCmkTargetStack(app, 'MultiRegionS3CrrKmsCmkTarget', {
env: { account: accountId, region: 'us-east-2' },
});
const sourceStack = new MultiRegionS3CrrKmsCmkSourceStack(app, 'MultiRegionS3CrrKmsCmkSource', {
env: { account: accountId, region: 'us-east-1' },
targetBucket: targetStack.targetBucket,
targetKeyIdSsmParameterName: targetStack.targetKeyIdSsmParameterName,
targetRegion: targetStack.region
});
sourceStack.addDependency(targetStack);
ADD CDK PIPELINES
CDK Pipelineを使用して、自動デプロイを実現します。
- CodeCommitへPushされる
- CodePipeline発火
- PreProd環境へデプロイ
- 手動承認
- Prod環境へデプロイ
import * as codecommit from "@aws-cdk/aws-codecommit"
import * as codepipeline from "@aws-cdk/aws-codepipeline"
import * as codepipeline_actions from "@aws-cdk/aws-codepipeline-actions"
import { Construct, SecretValue, Stack, StackProps } from "@aws-cdk/core"
import { CdkPipeline, SimpleSynthAction } from "@aws-cdk/pipelines"
import { MultiRegionS3CrrKmsCmkStage } from "./multi-region-s3-crr-kms-cmk-stage"
export class MultiRegionS3CrrKmsCmkPipelineStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps ){
super(scope, id, props)
const sourceArtifact = new codepipeline.Artifact()
const cloudAssemblyArtifact = new codepipeline.Artifact()
const pipeline = new CdkPipeline(this, "Pipeline", {
pipelineName: "MultiRegionS3CrrKmsCmkPipeline",
cloudAssemblyArtifact,
sourceAction: new codepipeline_actions.CodeCommitSourceAction({
actionName: "CodeCommit",
repository: codecommit.Repository.fromRepositoryName(this,
"CodeCommitRepo",
"cdk-pipelines-workshop",
),
output: sourceArtifact
}),
synthAction: SimpleSynthAction.standardNpmSynth({
sourceArtifact,
cloudAssemblyArtifact,
buildCommand: "npm run build"
})
})
const preProdStage = pipeline.addApplicationStage(new MultiRegionS3CrrKmsCmkStage(this, "PreProd", {
env: { account: props?.env?.account, region: "us-east-1" }
}))
preProdStage.addManualApprovalAction()
pipeline.addApplicationStage(new MultiRegionS3CrrKmsCmkStage(this, 'Production', {
env: { account: props?.env?.account, region: 'us-east-1' }
}));
}
}
感想
パッケージ化や自動デプロイについて、学ぶことができました。
CDK Pipelineを使って見たいと、思っていたのでちょうど良かったです。
通常のCDK Workshopをやってもう少し学びたい方におすすめです。