みなさん、こんにちは!
AWS CDKブログ第3回です!
ディレクトリ構成に続き、スタック構成・管理について検討します!
複数の環境がある場合のスタックをどう管理していくのか弊社なりにまとめた内容になっています。
前提として、第2回 AWS CDK ディレクトリ構成について考えてみた!のディレクトリ構成で説明していきます。
スタックとは
AWS CDK スタックとはデプロイされる最小単位です。
もう少し具体的に言えば、cdk deploy
コマンドしたときに作成されるAWSリソース群を管理する単位です。
AWS CDKはCFn (CloudFormation)で動いているので、CFnスタックとほぼ同じと考えるとイメージしやすいと思います。
例えば、VPCとS3バケットをAWSリソース群をまとめてデプロイするには、以下の様にスタックをクラスとして定義します。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as s3 from "aws-cdk-lib/aws-s3";
export class CdkWorkshopStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, "Vpc", {
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
maxAzs: 3,
});
// Bucketの作成
const bucket = new s3.Bucket(this, 'Bucket', {
});
}
}
スタック分割について
べスプラを確認するとスタックを分けないことが推奨されているように見受けられます。
通常、同じスタックにできるだけ多くのリソースを保持する方が簡単です。そのため、リソースを分離する必要があることがわかっていない限り、リソースをまとめておきます。
引用:AWS CDK を使用してクラウドインフラストラクチャを開発およびデプロイするためのベストプラクティス
CFnのリソース上限数が500のため、スタック内のAWSリソース数が500を超える場合はスタック分割が必須になります。
今回は、本番環境・ステージング環境・開発環境などの複数の環境でインフラを管理する場合、弊社は以下の観点から環境ごとにスタックを分ける方針を取った方がよいと考えました。
安全性
本番環境はビジネスクリティカルな環境のため、影響を極力避ける必要があります。
これはスタックを分けることで、ステージング環境や開発環境での変更・デプロイが本番に影響しない構造を作ることができます。
柔軟性
環境ごとに要件が異なる場合にもスタックを分けることで実現できます。
「本番環境・ステージング環境はマルチAZ構成とし、開発環境はシングルAZ構成とする。」といった要件が発生した場合は、スタックを個別に定義することで環境ごとに最適な構成が可能になります。
その他
その他にも、以下のような利点が挙げられます。
- 個別のCI/CDパイプラインやデプロイ戦略が組みやすくなる
- 障害の局所化・切り戻しが容易になる
- アカウントやリージョンの分離にも対応しやすくなる
スタック管理について
ここからはRe:Qで作成したCDKテンプレートのスタック構成・管理について説明していきます!
ディレクトリ構成がありきのスタック構成・管理になりますので、第2回 AWS CDK ディレクトリ構成について考えてみた!に記載されている情報が前提となります。
app定義
app定義では環境変数を参照し、どの環境のスタックを呼び出すかif文で定義しています。
※一部省略して記載しています。
const targetEnv = config.get('common.envPrefix');
const app = new cdk.App();
if (targetEnv === 'prd') {
new prd(app, `${targetEnv}`, {
});
} else {
new dev(app, `${targetEnv}`, {
});
}
stack定義
app定義で環境を意識しているのでスタックは、環境ごとstack定義ファイルを作成します。
例えば、本番環境であればマルチAZ構成でリソース群を構成するようにstack定義ファイルを作成し、開発環境はシングルAZ構成になるように別のstackファイルを作成します。
スタックの説明した際のコードを活用すると、以下2つのファイルを作成することで、環境ごとにスタックを分割し管理しています。
本番環境stack定義ファイル
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class prd extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, "Vpc", {
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
maxAzs: 3,
});
}
}
開発環境stack定義ファイル
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class dev extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, "Vpc", {
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
maxAzs: 1,
});
}
}
おわりに
本記事では、AWS CDKのスタックと弊社テンプレートのスタック構成・管理についてまとめました。
これらは安全性と柔軟性を考慮して作成しており、ぜひ参考にしていただければ幸いです!