はじめに
IaCを作成する時は、環境依存になるようなパラメータは外出ししてまとめて管理したいですよね?
パラメータを外出ししてまとめて管理しておくと、読み込む外出しパラメータ情報を切り替えるだけで、色々な環境をDeploy出来るので、構築コスト的にも好ましいですよね。
CDKには、パラメータを外出ししてまとめて管理する方法はいくつかあるんですが、その中から個人的に使っている以下2つをご紹介させて頂きます。
- node-configを利用する方法
- 自前TypeScriptで実装する方法
本記事では、「node-configを利用する方法」に関してご紹介させて頂きます。
「自前TypeScriptで実装する方法」に関しては、以下のリンクの記事をご確認ください。
自前TypeScriptで実装する方法
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。
node-configとは
「node-config」は、Node.jsの拡張ライブラリです。
node-config
本ライブラリを使用すると、パラメータファイルを事前に準備しておくことにより、アプリケーション実行時に環境変数NODE_ENVの値に紐ついたパラメータファイルを読み込み引き渡してくれます。
つまり、パラメータ等を外出しのファイルで管理することが出来ます。
また、外だしのパラメータファイルは、環境変数NODE_ENVの値に紐ついているので、環境が増加しても環境変数NODE_ENVの値とセットのパラメータファイルを追加するだけで大丈夫なため、コード変更が伴わず、パラメータをコードから切り離すことが出来ます。
つまり、CDKコード内でIF等の分岐処理で環境毎のパラメータをかき分ける実装が不要となりシンプルなコードにすることが出来ます。
言葉だけだと伝わり辛いと思いますので、実際の使い方を紹介させて頂きます。
使い方を見て頂けますと具体的なイメージが湧くと思われます。
node-config導入方法
「node-config」は下記コマンドでインストールできます。
$ npm install @types/config config
環境毎のパラメータファイルはプロジェクト直下にconfigディレクトリ格納するため、作成します。
$ mkdir ./config
これで事前準備は完了です。
実際にこれを用いて実装してみましょう。
node-configを用いた実装方法
実装は以下3ステップに分かれます。
- パラメータファイルを作成する
- Stackコードに引き渡す
- Stackコードからパラメータを受領する
それぞれのセクションに分けてご紹介させて頂きます。
パラメータファイルを作成する
パラメータファイルは環境毎に作成し、インストール時に作成したconfigディレクトリに配置します。
今回はサンプルとして「Dev.ts」という名前で作成します。
この名前を環境変数NODE_ENVに入れるため、重要な要素となります。
環境毎等の名前にしてしまうのが、使いやすいかと思われます。
//共通パラメータ
export const common = {
project: "parama-sample",
envPrefix: "dev",
accountId: "xxxxx"
};
//NW系パラメータ
export const nw = {
vpcCider: "10.0.0.0/24",
vpcMaxAZs: 2,
vpcPublicSubnetCidrMask: 27,
vpcPrivateSubnetCidrMask: 27,
};
//Aurora1用パラメータ
export const aurora1 = {
clusterParam: {
timezone: "Asia/Tokyo",
},
maxAurora: 4,
minAurora: 2,
};
上記のイメージのように目的毎に箱を作っていく形になります。
箱の中はkey:value形式であれば自由に組むことができ、Auora1の箱のClusterParamのようにネストされた構造を組むこともできます。
Stackコードに引き渡す
このサンプルでは、Stackコードにconfigモジュールインポートし、configのget Methodを用いて、後段のConstructコードに引き渡しています。
// node-configモジュールのインポート
import config = require("config");
export class SampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
//NW系Contructクラス
const nw = new Nw(this, "Nw", {
envName: config.get("common.envPrefix"),
vpcCider: config.get("nw.vpcCider"),
vpcMaxAZs: config.get("nw.vpcMaxAZs"),
vpcPublicSubnetCidrMask: config.get("nw.vpcPublicSubnetCidrMask"),
vpcPrivateSubnetCidrMask: config.get("nw.vpcPrivateSubnetCidrMask"),
});
//Aurora1用Constructクラス
const aurora1 = new aurora1(this, "aurora1", {
vpc: nw.myVpc,
envName: config.get("common.envPrefix"),
clusterParam: config.get("aurora1.clusterParam"),
maxAurora: config.get("aurora1.maxAurora"),
minAurora: config.get("aurora1.minAurora"),
import config = require("config");
ここでは、node-configモジュールをインポートしています。
requireを使っているのは、このモジュールがESモジュールでなく、CommonJSモジュールのためです。
Node.jsでは、多くのパッケージやモジュールがCommonJS方式で書かれています。
そのため、require()関数を使用してモジュールをインポートします。
envName: config.get("common.envPrefix"),
node-configモジュールのgetメソッドを使用して、Keyを指定(common.envPrefix)し、Dev.tsからデータを取得しています。
Stackコードからパラメータを受領する
ここからは、node-configモジュールを用いた、パラメータの引き渡しは関係ありません。
Stackから各Constructsのコードにパラメータは渡されているので、それを受領する部分となります。
export interface NwProps {
envName: string;
vpcCider: string;
vpcMaxAZs: number;
vpcPublicSubnetCidrMask: number;
vpcPrivateSubnetCidrMask: number;
}
export class Nw extends Construct {
public myVpc: ec2.Vpc;
constructor(scope: Construct, id: string, props: NwProps) {
super(scope, id);
// VPCの作成
this.myVpc = new ec2.Vpc(this, "Vpc", {
vpcName: `${props.envName}-Vpc`,
ipAddresses: ec2.IpAddresses.cidr(props.vpcCider),
maxAzs: props.vpcMaxAZs,
subnetConfiguration: [
{
cidrMask: props.vpcPublicSubnetCidrMask,
name: "Public",
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: props.vpcPrivateSubnetCidrMask,
name: "Private",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
});
export interface NwProps {
ここでは、このConstructsのインターフェースを定義しています。
Stackコードでは、このインターフェースを満たすようにpropsを渡してあげる必要があります。
public myVpc: ec2.Vpc;
StackコードのAurora1はNWからmyVpcが引き渡されています。
これを実現するためにここでpublicしています。
ipAddresses: ec2.IpAddresses.cidr(props.vpcCider),
Stackコードから渡されたvpcCiderを引き渡しています。
node-configを用いた実行方法
外だししたパラメータファイルからパラメータマップを行うために、環境変数NODE_ENVに環境名を設定します。
環境名はconfig/配下に作成するパラメータファイル名(Dev.ts)と同一のものを設定します。
$ export NODE_ENV=Dev
これで、Dev.tsのパラメータをCDK実行時にマップしてくれます。
パラメータ外だしに関連する作業は以上になります。
ここから先は、普段のCDK deploy時と同じ作業をして頂ければ問題ありません。
まとめ
以上が、node-configを用いたパラメータファイルの外だし方法になります。
環境変数に応じて、パラメータファイルを切り替えられるのが、非常に手軽で便利ですよね。
個人的には、CodeBuildでCDK deployをする際の親和性も非常に高いと感じています。
ご利用されたい場合は、ご紹介させて頂いた内容を参考にして頂けると幸いです。
この環境変数に応じて、パラメータファイルを切り替えが個人的にすごく魅力に感じており、それを取り込んだ自前TypeScript版は以下のリンクの記事でご紹介させて頂いてます。
自前TypeScriptで実装する方法
※ 主に使っているのはこっちです。余計なモジュール入れるのもな。。。ってことで
ご興味がありましたら、こちらも併せて参照して頂けますと幸いです。
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。