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

AWS

はじめに

システム開発をしていると、異なる環境(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のインターフェースを使用することで、予期しない値の設定やタイポのミスを防ぐことができます。

おわりに

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

参考

コメント