AWS CDK でパラメータを指定し環境依存を改善した話
はじめに
前回 AWS CDK を使って、CloudFront + S3 環境を構築しましたが、バケット名などが固定値であったため、検証/本番などそれぞれの環境用に TypeScript を作成する必要がありました。
そこでパラメータを利用し、そういった環境依存を解決する方法を調べました。
対象読者
- AWS CDK の導入を検討している方
- AWS CDK の運用に悩んでいる方
どのような方法があるか?
この記事が参考になりました。
抜粋
| 方法 | 概要 | 実行方法など |
|---|---|---|
| 1. Context variable | cdk.json や –c オプションで指定 | cdk deploy –c env=dev |
| 2. 環境変数 | CDK コマンド実行時に環境変数を指定 | ENV=dev cdk deploy |
| 3. 各言語のオブジェクト | CDK の言語でパラメータをハードコードする | 例えば、TypeScript の object で値を指定する |
| 4. AWS Systems Manager Parameter Store | CDK 外でパラメータを作成 deploy 時に CFn が値を読込 | AWS Systems Manager Parameter Store 経由で値を渡す |
| 5. CfnParameter | CloudFormation の Parameter 機能を使う | cdk deploy --parameters hoge=fuga |
試してみました
実行環境は前回のとおりです。
下記 Stack をサンプルとし、それぞれの方法で実行してみます。
( CDK は TypeScript です。)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
console.log("dev");
}
}
実行結果は以下の通りです。
(プロンプトに dev が表示されれば OK です。)
my-cdk-app> cdk deploy
dev
1. Context variable
CDK 実行時、cdk.json に指定したパラメータを読み込む方法
{
"context": {
"dev": {
"envValue": "hoge"
},
"prod": {
"envValue": "fuga"
}
}
}
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const env = this.node.tryGetContext("env");
const conf = this.node.tryGetContext(env);
console.log(conf.envValue);
}
}
実行結果は以下の通りです。
(env=dev 指定時は hoge、env=prod 指定時は fuga が表示されれば OK です。)
my-cdk-app> cdk deploy -c env=dev
hoge
my-cdk-app> cdk destroy -c env=dev
my-cdk-app> cdk deploy -c env=prod
fuga
my-cdk-app> cdk destroy -c env=prod
2. 環境変数
CDK 実行前に環境変数を指定する方法
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const envValue = process.env.ENV_VALUE ?? "hoge";
console.log(envValue);
}
}
実行結果は以下の通りです。
my-cdk-app> $env:ENV_VALUE = "hoge"; cdk deploy
hoge
my-cdk-app> cdk destroy
my-cdk-app> $env:ENV_VALUE = "fuga"; cdk deploy
fuga
my-cdk-app> cdk destroy
3. 各言語のオブジェクト
CDK プロジェクト内で TypeScript 用の config.ts を作り、環境設定を書く方法
export const config = {
dev: {
envValue: "hoge",
},
prod: {
envValue: "fuga",
},
} as const;
export type EnvName = keyof typeof config;
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { config, type EnvName } from "./config";
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const envName = (this.node.tryGetContext("env") ?? "dev") as EnvName;
const conf = config[envName];
console.log(conf.envValue);
}
}
実行結果は以下の通りです。
(env=dev 指定時は hoge、env=prod 指定時は fuga が表示されれば OK です。)
my-cdk-app> cdk deploy -c env=dev
hoge
my-cdk-app> cdk destroy
my-cdk-app> cdk deploy -c env=prod
fuga
my-cdk-app> cdk destroy
4. AWS Systems Manager Parameter Store
パラメータを AWS Systems Manager Parameter Store で設定する方式
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ssm from 'aws-cdk-lib/aws-ssm';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// SSM に値をセット
const ssmParameter = new ssm.StringParameter(this, 'set_parameter', {
parameterName: 'envValue',
stringValue: 'hoge',
description: 'Environment Value',
});
new cdk.CfnOutput(this, 'EnvValueOutput', {
value: ssmParameter.stringValue,
description: 'SSM Parameter Value',
exportName: 'EnvValue',
});
}
}
実行結果は以下の通りです。
(Outputs で hoge が表示されれば OK です。)
my-cdk-app> cdk deploy
Outputs:
MyCdkAppStack.EnvValueOutput = hoge
my-cdk-app> cdk destroy
5. CfnParameter
CDK コマンド実行時に Parameter を指定する方法
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const param = new cdk.CfnParameter(this, "EnvValue", {
type: "String",
default: "hoge",
});
new cdk.CfnOutput(this, 'EnvValueOutput', {
value: param.valueAsString,
});
}
}
実行結果は以下の通りです。
(未指定時に hoge、EnvValue=fuga 指定時 fuga が表示されれば OK です。)
my-cdk-app> cdk deploy
Outputs:
MyCdkAppStack.EnvValueOutput = hoge
my-cdk-app> cdk destroy
my-cdk-app> cdk deploy --parameters EnvValue=fuga
Outputs:
MyCdkAppStack.EnvValueOutput = fuga
my-cdk-app> cdk destroy
おまけ:.env ファイルで指定
.env ファイル内に環境依存のパラメータを指定する方法
(個人的にはこれが一番しっくりくる)
- 実行前に dotenvをインストール
my-cdk-app> npm install dotenv --save
ENV1_VALUE=hoge
ENV2_VALUE=fuga
ENV3_VALUE=piyo
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dotenv from 'dotenv';
export class MyCdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
dotenv.config();
console.log(process.env.ENV1_VALUE);
console.log(process.env.ENV2_VALUE);
console.log(process.env.ENV3_VALUE);
}
}
実行結果は以下の通りです。
my-cdk-app> cdk deploy
hoge
fuga
piyo
my-cdk-app> cdk destroy
やってみた結果(感想)
参考サイトでは、下記の順番でおすすめでした。
私的には4番以外はプログラム変更が必要だったり、CDK実行時にコマンドでパラメータを指定しなきゃいけなかったりで、ちょっと管理や運用が大変だと感じました。
(4 はパラメータ値を秘匿できるのが良い点ですよね!)
個人的な「なれ」もありますが、「おまけ:.env ファイルで指定」が扱いやすいんじゃないかと!
まとめ
今回は CDK の環境依存を解消したくいろいろとやってみました。
CLI(Command Line Interface:コマンドラインインターフェイス)でパラメータを指定する時にタイポしてひどい目に遭ったことがあり、パラメータ入力が苦手 (キライ) なんです。😓
なので、できる限り自分で入力しなくて済む方法が、私的には安心できるので採用しちゃいますね!
この記事が、誰かのお役に立てば幸いです。
Discussion