CDK L2とは?
CDK にはコンストラクトと呼ばれる、リソースを構成する構成要素が存在します。
そして、そのコンストラクトには、Layerが存在し、Layer1・2・3が存在します。
その違いは、ズバリ抽象度です。
L1 (Layer1) は、CloudFormationのテンプレートをほとんどそのままCDKで記述するイメージで、抽象度がかなり低く、1つ1つのリソースを細かく定義していく必要があります。
したがって、コード量は多くなります。
Layer1ではCfnというクラスを用い、記述します。
L2 (Layer2) は抽象度の高い記述方法で、すべてのリソースを一つ一つ記述せずとも、AWSが自動で必要なリソースをデプロイしてくれます。したがって、コード量は少なくなり、また、AWSリソースの詳細をすべて知る必要がなくなります。
L3(Layer3)はさらに抽象度の高い記述方法ですが、今回は割愛します。
一般的によく使われるのは、L2だと思います。
コンストラクトについてのAWSの説明はこちらです。
L1 — これらは Cfn (CloudFormation の略) リソースと呼ばれる低レベルの Construct です。これらは AWS CloudFormation リソース仕様から定期的に生成されます。名前パターンは CfnXyz で、 Xyz はリソースの名前です。これらの Construct を使用するときは、すべてのリソースプロパティを設定する必要があります。そのためには、基礎となる CloudFormation リソースモデルとそれに対応する属性を十分に理解している必要があります。
L2 — これらは、より高いレベルの使用用途に応じた便利な API を備えた AWS リソースを表します。デフォルトの設定、定型コード、コンポーネント間を簡単に結合するロジックなど、 L1 Construct を使って自分で開発するような追加機能を提供します。 AWS Construct には便利なデフォルト設定が用意されており、それが表す AWS リソースの詳細をすべて知る必要がなくなります。リソースの操作をよりシンプルにするための便利なメソッドが提供され、結果的にアプリケーションを作成することが簡単になります
CDK L2の真価を証明していく!!
実際にコードを用いてCDK L2の真価を証明します。今回はCDKと同じくIaCの仲間である、Terraformとコード量を比較したいと思います。
今回は作成するリソースは以下です。
・VPC
・サブネット
・IGW
・ルートテーブル
terraformで書くと、以下のようになります。
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.main.id
route_table_id = aws_route_table.public.id
}
ご覧のように、terraformで記述すると、一つ一つのリソースを丁寧に細かく明示的に記述する必要があります。
考えられるデメリットとしては、以下でしょうか。
・コード量が多くなる。
・AWSリソースについての知識が必要となる。
ただ、AWSの知識があるが、プログラミング言語には慣れていない人にとってとっつきやすいかもしれません。リソースの設定値が明示的になっているので、直感で理解しやすいです。
では、続いてCDKで同じ構成を作成してみます。(今回はTypescriptで記述しています。)
import { Stack, Tags } from "aws-cdk-lib";
import { Construct } from "constructs";
import { Vpc as DemoVpc, SubnetType, IpAddresses } from "aws-cdk-lib/aws-ec2";
export class DemoStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const vpc = new DemoVpc(this, "demo-vpc", {
ipAddresses: IpAddresses.cidr("10.0.0.0/16"),
maxAzs: 1,
subnetConfiguration: [
{
name: "demo-subnet",
subnetType: SubnetType.PUBLIC,
cidrMask: 24,
},
],
});
Tags.of(vpc).add("Name", "demo-vpc");
}
}
で、これをcdk deployすると、、、

VPCとサブネットが作成され、ルートテーブルが設定されており、、、

ルートテーブルを確認すると、インターネットゲートウェイも作成され、ターゲットに指定されていました!
DemoStackという1つのクラスの中で、VPCとサブネットを作成しているだけです。
これだけで、VPC・サブネット、そしてゲートウェイやルートテーブルまで作成してくれます。
そのため、コードの削減にもつながりますし、AWSリソースの詳細を細かく知る必要もありません。
デメリットとしては、直感的に設定値がわかりにくく、また、プログラミングに慣れていない人にとっては学習難易度が高そうです。
以上、Terraform と CDKの比較、そしてCDK L2の真価の披露でした。