前提など
構築の前提や準備などは前回の記事を参照してください。
作成したコード
ひとまず完成したコードがこちらです。
L1コンストラクトで書いてます。コンストラクトについては後日書きたいと思います。
細かく設定したいのでL1を利用しましたが、L2、L3と抽象度が上がるにつれて記載するコードが少なくなっていきます。
(ファイル名は構成とずれてます、、、)
import * as cdk from '@aws-cdk/core';
import {
CfnVPC,
CfnSubnet,
CfnInternetGateway,
CfnVPCGatewayAttachment,
CfnRouteTable,
CfnRoute,
CfnSubnetRouteTableAssociation,
VpcEndpoint
} from '@aws-cdk/aws-ec2';
export class Aws1Vpc3PrivateSubnetStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const systemName = this.node.tryGetContext('systemName');
const envType = this.node.tryGetContext('envType');
//VPC
const vpc = new CfnVPC(this, 'Vpc', {
cidrBlock: '10.0.0.0/16',
tags: [{ key: 'Name', value: `${systemName}-${envType}-vpc` }]
});
//InternetGateway
const igw = new CfnInternetGateway(this, 'igw', {
})
new CfnVPCGatewayAttachment(this, 'igwAttachment', {
internetGatewayId: igw.ref,
vpcId: vpc.ref
})
//PublicSubnet
const subnetPublic1a = new CfnSubnet(this, 'SubnetPublic1a', {
cidrBlock: '10.0.0.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1a',
mapPublicIpOnLaunch: true,
tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1a-1` }]
})
const subnetPublic1c = new CfnSubnet(this, 'SubnetPublic1c', {
cidrBlock: '10.0.1.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1c',
mapPublicIpOnLaunch: true,
tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1c-1` }]
})
const subnetPublic1d = new CfnSubnet(this, 'SubnetPublic1d', {
cidrBlock: '10.0.2.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1d',
mapPublicIpOnLaunch: true,
tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1d-1` }]
})
//PrivateSubnet
const subnetPrivate1a1 = new CfnSubnet(this, 'SubnetPrivate1a1', {
cidrBlock: '10.0.10.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1a',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1a-1` }]
})
const subnetPrivate1a2 = new CfnSubnet(this, 'SubnetPrivate1a2', {
cidrBlock: '10.0.20.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1a',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1a-2` }]
})
const subnetPrivate1c1 = new CfnSubnet(this, 'SubnetPrivate1c1', {
cidrBlock: '10.0.11.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1c',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1c-1` }]
})
const subnetPrivate1c2 = new CfnSubnet(this, 'SubnetPrivate1c2', {
cidrBlock: '10.0.21.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1c',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1c-2` }]
})
const subnetPrivate1d1 = new CfnSubnet(this, 'SubnetPrivate1d1', {
cidrBlock: '10.0.12.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1d',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1d-1` }]
})
const subnetPrivate1d2 = new CfnSubnet(this, 'SubnetPrivate1d2', {
cidrBlock: '10.0.22.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1d',
mapPublicIpOnLaunch: false,
tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1d-2` }]
})
//RouteTable
const publicRouteTable = new CfnRouteTable(this, 'PublicRouteTable', {
vpcId: vpc.ref,
tags: [{
key: 'Name',
value: `${systemName}-${envType}-Public-RouteTable`,
}]
})
new CfnRoute(this, 'PublicRoute', {
routeTableId: publicRouteTable.ref,
destinationCidrBlock: '0.0.0.0/0',
gatewayId: igw.ref,
})
new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1aRouteTableAssociation', {
routeTableId: publicRouteTable.ref,
subnetId: subnetPublic1a.ref
})
new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1cRouteTableAssociation', {
routeTableId: publicRouteTable.ref,
subnetId: subnetPublic1c.ref
})
new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1dRouteTableAssociation', {
routeTableId: publicRouteTable.ref,
subnetId: subnetPublic1d.ref
})
const privateRouteTable = new CfnRouteTable(this, 'privateRouteTable', {
vpcId: vpc.ref,
tags: [{
key: 'Name',
value: `${systemName}-${envType}-Private-RouteTable`,
}]
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a1RouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1a1.ref
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1c1RouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1c1.ref
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1d1dRouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1d1.ref
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a2RouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1a2.ref
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1c2RouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1c2.ref
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1d2dRouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1d2.ref
})
}
}
細かく見ていきます。
インポート
各種パッケージをインポートしています。
ここでインポートするためには、事前にディレクトリ内でnpm installします。ここでは、npm install @aws-cdk/aws-ec2
が必要です。
import * as cdk from '@aws-cdk/core';
import {
CfnVPC,
CfnSubnet,
CfnInternetGateway,
CfnVPCGatewayAttachment,
CfnRouteTable,
CfnRoute,
CfnSubnetRouteTableAssociation,
VpcEndpoint
} from '@aws-cdk/aws-ec2';
スタック定義
ここからがスタック定義になります。
cdk.Stack
を継承したAws1Vpc3PrivateSubnetStack
クラスに構築したいリソースを定義していきます。
デプロイするとAws1Vpc3PrivateSubnetStack
というCfnスタックが作成されます。
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {super(scope, id, props);
でコンストラクトの定義をしていますが、基本的にはそのままでも問題ないです。
最後の2行は変数を定義しています。ここで参照されるsystemName
とenvType
はcdk.json
のcontext
内で定義します。
export class Aws1Vpc3PrivateSubnetStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const systemName = this.node.tryGetContext('systemName');
const envType = this.node.tryGetContext('envType');
VPC
VPCリソースはCidrBlockとTagを指定しています。
const vpc = new CfnVPC(this, 'Vpc', {
cidrBlock: '10.0.0.0/16',
tags: [{ key: 'Name', value: `${systemName}-${envType}-vpc` }]
});
InternetGateway
igwインスタンスを作成して、VPCにアタッチします。
const igw = new CfnInternetGateway(this, 'igw', {
})
new CfnVPCGatewayAttachment(this, 'igwAttachment', {
internetGatewayId: igw.ref,
vpcId: vpc.ref
})
Subnet
基本的にパブリックもプライベートも同じ定義ですが、mapPublicIpOnLaunch
のみtrue
がパブリック、false
がプライベートです。指定しないとfalseが設定されます。
const subnetPublic1a = new CfnSubnet(this, 'SubnetPublic1a', {
cidrBlock: '10.0.0.0/24',
vpcId: vpc.ref,
availabilityZone: 'ap-northeast-1a',
mapPublicIpOnLaunch: true,
tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1a-1` }]
})
RouteTable
RouteTableの作成には、RouteTable、Route、Associationの3つの要素があります。
const publicRouteTable = new CfnRouteTable(this, 'PublicRouteTable', {
vpcId: vpc.ref,
tags: [{
key: 'Name',
value: `${systemName}-${envType}-Public-RouteTable`,
}]
})
new CfnRoute(this, 'PublicRoute', {
routeTableId: publicRouteTable.ref,
destinationCidrBlock: '0.0.0.0/0',
gatewayId: igw.ref,
})
new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1aRouteTableAssociation', {
routeTableId: publicRouteTable.ref,
subnetId: subnetPublic1a.ref
})
localへのRoute定義以外が必要な場合はRoute定義が必要ですが、必要ない(プライベートサブネットにアタッチする)場合は、Route定義は不要です。
const privateRouteTable = new CfnRouteTable(this, 'privateRouteTable', {
vpcId: vpc.ref,
tags: [{
key: 'Name',
value: `${systemName}-${envType}-Private-RouteTable`,
}]
})
new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a1RouteTableAssociation', {
routeTableId: privateRouteTable.ref,
subnetId: subnetPrivate1a1.ref
})
最後に
今回作成したリソースはデプロイしても料金のかからないものばかりなので、CDKの勉強にはちょうど良いかなと思っています。
実際は疎通確認用のEC2やNATGatewayを含んだスタックにする方が、利用用途は多くなると思います。
今後はそういったリソースもチャレンジしていきたいと思います。TypeScript初心者なので、コードが汚いのはご容赦ください。
今回作成したコードはこちらです。