AWS CDKで環境ごとのスタックを効率的に管理する

AWS CDKで環境ごとのスタックを効率的に管理する

はじめに

システム開発をしていると、異なる環境(dev,stg,prodなど)に対して、異なる設定値を持たせたいケースがあるかと思います。 本記事では、TypeScriptの力を活用して、各環境ごとの設定を効率的に管理する方法を紹介します。

実装方法の概要

スタックを環境ごとに定義し、環境ごとのパラメータは外部のparameter.tsファイルにパラメータを保存し、それをメインのスタックファイルでインポートします。 これにより一度のsynthコマンドで複数環境向けのCloudFormationテンプレートを生成することができ、以下のメリットを享受できます。

  • 効率性: 各環境に対応したテンプレートを同時に生成できるため、デプロイの工程が簡素化されます。

  • 整合性: 一度の定義で複数のテンプレートを生成できるため、環境間での差異を最小限に抑えることができます。

  • 管理のしやすさ: 一つのCDKアプリケーションで全ての環境のスタックを管理することで、コードの一元管理が可能になります。

parameter.tsの作成

このparameter.tsファイルは、環境別の設定やリソースを定義する場所となります。

import { Environment } from 'aws-cdk-lib';

export interface MyParameter {
 env?: Environment;
 envName: string;
 branchName: string;
}

export const devParameter: MyParameter = {
 envName: 'dev',
 branchName: 'develop',
}

export const prodParameter: MyParameter = {
 envName: 'prod',
 branchName: 'production',
}
  • MyParameterインターフェースで、どのようなパラメータを管理したいのかを定義します。今回は環境名やブランチ名などの情報を持つMyParameterというインターフェースを定義しています。

  • devParameterprodParameterといった各環境の具体的な環境設定をこのインターフェースに基づいて定義します。

主要なスタックファイルの変更

スタック定義ファイルbin/cdk-demo.tsで、先程作成したparameter.tsをインポートします。これにより、スタック作成時にそれぞれの環境に適したパラメータが適用されるようになります。

import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkDemoStack } from '../lib/cdk-demo-stack';
import { devParameter, prodParameter } from '../parameter'

const app = new cdk.App();
new CdkDemoStack(app, 'DevStack', {
 envName: devParameter.envName,
 branchName: devParameter.branchName
});

new CdkDemoStack(app, 'ProdStack', {
 envName: prodParameter.envName,
 branchName: prodParameter.branchName
});

リソースの実際の使用方法

具体的なリソース、例えばCodeBuildプロジェクトの定義では、lib/cdk-demo-stack.tsでこれらのパラメータを取り込み、実際のリソースのプロパティとして設定します。この記事の例では、GitHubのリポジトリ名やブランチに基づいて、CodeBuildのビルドトリガーを設定しています。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

export interface stackProps extends cdk.StackProps {
 envName: string;
 branchName: string;
}

export class CdkDemoStack extends cdk.Stack {
 constructor(
 scope: Construct,
 id: string,
 props: stackProps
 ) {
 super(scope, id, props);

 const {
 envName,
 branchName,
 } = props;

 // codebuild
 const gitHubSource = codebuild.Source.gitHub({
 owner: 'masawai',
 repo: 'jumble',
 webhook: true,
 webhookFilters: [
 codebuild.FilterGroup
 .inEventOf(codebuild.EventAction.PULL_REQUEST_CREATED, codebuild.EventAction.PULL_REQUEST_REOPENED)
 .andBaseBranchIs(branchName)
 ],
 });

 const buildProject = new codebuild.Project(this, 'buildProject', {
 source: gitHubSource,
 buildSpec: codebuild.BuildSpec.fromObject({
 version: '0.2',
 phases: {
 install: {
 'runtime-versions': {
 python: "3.8"
 },
 },
 build: {
 commands: [
 'echo test',
 ]
 },
 },
 }),
 environment: {
 buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
 environmentVariables: {
 ENV: {
 type: codebuild.BuildEnvironmentVariableType.PLAINTEXT,
 value: envName,
 }
 },
 }
 });

 }
}

スタックのデプロイ

cdk deployコマンドを使用してスタックをデプロイします。

特定のスタックだけをデプロイしたい場合は、デプロイしたいスタックの名前をコマンドの後に追加します。例えば、bin/cdk-demo.tsで定義したDevStackのみをデプロイしたい場合は、以下のコマンドを実行します。同様に、他のスタックもデプロイすることができます。

$ cdk deploy DevStack

この方法の利点

  • 一元管理:すべての環境設定を一箇所で管理できるため、変更や追加が簡単です。

  • 可読性の向上:各環境の設定が明確に分かれているため、コードの可読性が向上します。

  • 型安全:TypeScriptのインターフェースを使用することで、予期しない値の設定やタイポのミスを防ぐことができます。

おわりに

本記事では、各環境ごとの設定を効率的に管理する方法を紹介しました。 この記事がどなたかの参考になれば幸いです。

参考