あんパン

こしあん派

CDKで複数の環境にデプロイしたいStackを書くときにやっていること

最近CDKを書くことがちまちまあって、手癖としてこんなことやっていますという紹介。世間のベストプラクティスみたいなのをあんまり収集しているわけではないのでこれがいいやり方なのかはよく分かっていない。一応 Best practices for developing and deploying cloud infrastructure with the AWS CDK - AWS Cloud Development Kit (AWS CDK) v2 とか公式ドキュメント系は読んでます、くらいのレベル感。もっといいやり方あるよなどがあれば教えてください。

ここで取り上げたいのは同じStackをdevelop, staging, productionなど複数の環境に対してデプロイしたいケース。

export const stages = ['develop', 'staging', 'production'] as const;
export type StageName = typeof stages[number];
export class Config {
  public readonly stage: StageName;

  constructor(stage: StageName) {
    this.stage = stage;
  }

  genId(id: string) {
    return ['service-name', this.stage, id].join('-');
  }
}

みたいなのを lib/util.ts とかに用意しておいて bin/*.ts

import * as cdk from 'aws-cdk-lib';
import { HogeStack } from '../lib/hoge-stack';
import { stages, Config } from '../lib/util';

const app = new cdk.App();

for (const stage of stages) {
  const config = new Config(stage);
  new HogeStack(app, config.genId('hoge'), {});
}

みたいな感じにしている。こうすると

$ cdk ls
service-name-develop-hoge
service-name-production-hoge
service-name-staging-hoge

こうなる。Stackが複数になったとしても、develop環境だけデプロイしたいときは cdk deploy 'service-name-develop-*' みたいな感じでデプロイできる。単純に -c オプションで環境を与えて場合分けするパターンと比較したメリットとしては cdk ls するだけでひととおりのStackを一覧できる(環境含めてどんなStackがあるのか分かりやすい)、若干スナップショットテストしやすいとかだろうか。あとはStackの名前が揃うのでCloudFormationのWebコンソール上で探しやすいとか?

設定値を差し込みたいときは cdk.json のcontextに環境ごとの値を書いて、Configでappを受け取って app.node.tryGetContext(stage) で抜き出してConfigのプロパティに設定する、みたいなのを普通にやるイメージ。