🗂

AWS CDKでDev/Staging/Production環境のスタックを作る

2024/02/03に公開

AWS CDKを使うとインフラのコード化ができます。インフラ環境はDevelop/Staging/Productionなど複数の環境を持つことが多いと思います。今回はAWS CDKで同一のスタックを複数の環境に適用するための方法を紹介します。いくつかやり方がありますが、今のところこれが一番しっくり来ています。

CDKコマンド実行例

スタック名の後ろにハイフン区切りで環境名を付与しています。

# CDKコマンド実行例
npx cdk synth Sample-develop # develop環境
npx cdk synth Sample-staging # staging環境
npx cdk synth Sample-production # production環境

-c enviroment=develop というオプションを渡す方式もあるのですが、ここで指定した環境名をスタック名に反映させる良い方法が思いつかなかったので、スタック名から環境名を引っ張ってくるようにしています。

./bin/cdk.ts

cdk.tsでは複数環境のスタックを初期化します。

#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { SampleStack } from "../lib/sample-stack";

const app = new cdk.App();
const stages = ["develop", "staging", "production"] as const;
for (const stage of stages) {
  new SampleStack(app, `Sample-${stage}`, {
    // Availability zoneを3つ以上指定するにはアカウントとリージョンを指定する必要がある
    // この環境変数はAWSプロファイルが設定されている場合は自動でセットされる
    env: {
      account: process.env.CDK_DEFAULT_ACCOUNT,
      region: process.env.CDK_DEFAULT_REGION,
    },
  });
}

./cdk.json

もし環境ごとに異なる値を使いたい場合は cdk.json の context というキーを使うことで呼び出すことができます。

{
  "context": {
    "develop": {
      "key1": "foo-develop",
    },
    "staging": {
      "key1": "foo-staging",
    },
    "production": {
      "key1": "foo-production",
    }
  }
}

./lib/sample-stack.ts

スタック初期化の第二引数にスタック名が渡ってくるのでハイフンで区切って環境名を取得します。そして、cdk.jsonで定義した環境ごとの値を tryGetContext を使って読み込んでいます。

export class SampleStack extends Stack {
  private envValues: { [key: string]: string };

  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // cdk.jsonで定義した環境ごとの定数を参照
    const [_, envKey] = id.split("-");
    this.envValues = scope.node.tryGetContext(envKey) as {
      [key: string]: string;
    };
    console.log(envKey.key1); // foo-something
  }
}

以上です。もっと良い方法があればぜひ教えて下さい。

ムーザルちゃんねる

Discussion