AWS CDK(Cloud Development Kit)はTypeScriptやJavaなどのコードから CloudFormationのテンプレートを生成して差分を確認しデプロイできる公式のツール。まだdeveloper preview。
$ npm i -g aws-cdk
$ cdk --version
0.33.0 (build 50d71bf)
$ mkdir cdk-vpc
$ cd cdk-vpc
$ cdk init app --language=typescript
CloudFormationのリソースと対応するCfnFoo
や、それを内部で作成する高レベル(L2)のResource ClassFoo
が実装されている。
ただし、現状CfnFoo
に対応するResource Classが存在しないものや、複数のリソースを内部で作成するResource Classが存在する。
例えば、ec2.VpcはCfnVPCだけではなく、Public/Private Subnet、NATGatewayまでまとめて一般的な構成で作る。Resource Classはまだ変更が多い。
CloudFormationでVPCを作成してLambdaをデプロイしAurora Serverlessを使う - sambaiz-net
型があり補完が効くので通常のテンプレートと比べて書きやすいし、ループしたりすることもできる。
import * as cdk from '@aws-cdk/cdk'
import * as ec2 from '@aws-cdk/aws-ec2'
interface Export {
vpc: ec2.Vpc
}
export class VPCStack extends cdk.Stack {
protected deployEnv: string
export: Export
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props)
this.deployEnv = this.node.getContext('env')
const vpc = this.vpc()
this.export = {
vpc: vpc
}
}
private vpc() {
let cidr: string | null
if (this.deployEnv === 'stg') {
cidr = '172.32.1.0/24'
} else if (this.deployEnv === 'prd') {
cidr = '172.32.2.0/24'
} else {
throw new Error(`unknown env ${this.deployEnv}`)
}
return new ec2.Vpc(this, `${this.deployEnv}-vpc`, {
cidr: cidr,
maxAZs: 2,
subnetConfiguration: [
{
cidrMask: 26,
subnetType: ec2.SubnetType.Public,
name: `${this.deployEnv}-vpc-public`
},
{
cidrMask: 26,
subnetType: ec2.SubnetType.Private,
name: `${this.deployEnv}-vpc-private`
}
]
})
}
}
プロパティを渡せばRefやGetAttになる。Stack間のExportやImportValueも同様で、さらに依存関係を考慮した順序でStackを更新してくれる。
必要であればcdk.Fn.ImportValue()
で外部からImportValueしたり、
cdk.CfnOutput()
でOutputすることもできる。
Serverless FrameworkなどのCDK外StackからImportする際は、自動で作られたExportはCDK内で依存がなくなると消そうとしてしまうので、
明示的にExportしたものをImportした方が良さそう。
const vpcStackExport = new VPCStack(app, `${deployEnv}VPCStack`).export
new SomeAppStack(app, `${deployEnv}SomeAppStack`, {
dbSubnetIds: vpcStackExport.vpc.privateSubnets.map(v => v.subnetId)
})
cdk synth
でテンプレートを出力して確認できる。
$ npm run build
$ cdk synth -o ./outputs
./outputs/CdkVpcStack.template.yaml
cdk diff
で作成/削除されるリソースを見て、
$ cdk diff
Stack CdkVpcStack
Resources
[+] AWS::EC2::VPC test-vpc testvpc8985080E
[+] AWS::EC2::Subnet test-vpc/test-publicSubnet1/Subnet testvpctestpublicSubnet1SubnetF24995A1
[+] AWS::EC2::RouteTable test-vpc/test-publicSubnet1/RouteTable testvpctestpublicSubnet1RouteTableF3DE8760
[+] AWS::EC2::SubnetRouteTableAssociation test-vpc/test-publicSubnet1/RouteTableAssociation testvpctestpublicSubnet1RouteTableAssociation13140377
[+] AWS::EC2::Route test-vpc/test-publicSubnet1/DefaultRoute testvpctestpublicSubnet1DefaultRoute06B168C8
[+] AWS::EC2::EIP test-vpc/test-publicSubnet1/EIP testvpctestpublicSubnet1EIP5E036D64
...
cdk deploy
でデプロイできる。
$ cdk deploy
CdkVpcStack: deploying...
CdkVpcStack: creating CloudFormation changeset...
0/25 | 20:59:21 | CREATE_IN_PROGRESS | AWS::EC2::EIP | test-vpc/test-publicSubnet2/EIP (testvpctestpublicSubnet2EIPCB02013C)
0/25 | 20:59:21 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata
0/25 | 20:59:22 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | test-vpc/IGW (testvpcIGW2C2BA83F)
0/25 | 20:59:22 | CREATE_IN_PROGRESS | AWS::EC2::EIP | test-vpc/test-publicSubnet1/EIP (testvpctestpublicSubnet1EIP5E036D64)
...