AWS CDKでAutoScaling環境を作成(Single Stack / Nested Stack)
AWS CDK ExampleのEC2をコードリーディングしてみたので、簡易まとめです。 前提バージョン セットアップ AWS CDKプロジェクトのセットアップ まずはCDKでプロジェクトを作成します。 必要なリソースの […]
広告ここから
広告ここまで
目次
AWS CDK ExampleのEC2をコードリーディングしてみたので、簡易まとめです。
前提バージョン
$ cdk --version
0.14.1 (build c87f3ec)
$ node -v
v10.5.0
セットアップ
AWS CDKプロジェクトのセットアップ
まずはCDKでプロジェクトを作成します。
$ mkdir autoscaling
$ cd autoscaling
$ cdk init app --language=typescript
必要なリソースのインストール
- VPC
- AutoScaling Group
- ELB (Classic Load Balancer)
この3つを用意します。必要なパッケージを追加しましょう。
$ npm i -S @aws-cdk/[email protected] @aws-cdk/[email protected] @aws-cdk/[email protected]
Single Stackで作成する
まずはベーシックな使い方な1スタック方式でつくります。
#!/usr/bin/env node
import ec2 = require('@aws-cdk/aws-ec2');
import autoscaling = require('@aws-cdk/aws-autoscaling');
import elb = require('@aws-cdk/aws-elasticloadbalancing')
import cdk = require('@aws-cdk/cdk');
class AppWithVpc extends cdk.Stack {
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
super(parent, name, props)
// VPCネットワークの作成
const vpc = new ec2.VpcNetwork(this, 'MyVPC')
// AutoScaling Groupをセットアップする
const asg = new autoscaling.AutoScalingGroup(this, 'ExampleASG', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.T2, ec2.InstanceSize.Small),
machineImage: new ec2.AmazonLinuxImage()
})
// Classic Load Balancerを作成
const clb = new elb.LoadBalancer(this, 'LB', {
vpc,
internetFacing: true
})
clb.addListener({ externalPort: 80})
clb.addTarget(asg)
}
}
const app = new cdk.App()
new AppWithVpc(app, 'app-with-vpc')
app.run()
以下のコマンドでCloudFormationのYAMLファイルに出力できます。
$ npm run build
$ cdk synth
出力結果がこちら。new ec2.VpcNetwork(this, 'MyVPC')
だけでセキュリティグループなども作ってくれています。
Resources:
MyVPCAFB07A31:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC
MyVPCPublicSubnet1Subnet0C75866A:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.0.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2a
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet1
MyVPCPublicSubnet1RouteTable538A9511:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet1
MyVPCPublicSubnet1RouteTableAssociation8A950D8E:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet1RouteTable538A9511
SubnetId:
Ref: MyVPCPublicSubnet1Subnet0C75866A
MyVPCPublicSubnet1DefaultRouteAF81AA9B:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet1RouteTable538A9511
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: MyVPCIGW30AB6DD6
MyVPCPublicSubnet1EIP5EB6147D:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
MyVPCPublicSubnet1NATGateway838228A5:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- MyVPCPublicSubnet1EIP5EB6147D
- AllocationId
SubnetId:
Ref: MyVPCPublicSubnet1Subnet0C75866A
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet1
MyVPCPublicSubnet2Subnet4DDFF14C:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.32.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2b
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet2
MyVPCPublicSubnet2RouteTableA6A1CD3D:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet2
MyVPCPublicSubnet2RouteTableAssociationF22D63CA:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet2RouteTableA6A1CD3D
SubnetId:
Ref: MyVPCPublicSubnet2Subnet4DDFF14C
MyVPCPublicSubnet2DefaultRoute24460202:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet2RouteTableA6A1CD3D
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: MyVPCIGW30AB6DD6
MyVPCPublicSubnet2EIP6F364C5D:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
MyVPCPublicSubnet2NATGateway4D6E78B8:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- MyVPCPublicSubnet2EIP6F364C5D
- AllocationId
SubnetId:
Ref: MyVPCPublicSubnet2Subnet4DDFF14C
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet2
MyVPCPublicSubnet3Subnet1F5F6FC2:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.64.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2c
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet3
MyVPCPublicSubnet3RouteTableAC210F4D:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet3
MyVPCPublicSubnet3RouteTableAssociation2F72E244:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet3RouteTableAC210F4D
SubnetId:
Ref: MyVPCPublicSubnet3Subnet1F5F6FC2
MyVPCPublicSubnet3DefaultRouteB9A2FDF0:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPublicSubnet3RouteTableAC210F4D
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: MyVPCIGW30AB6DD6
MyVPCPublicSubnet3EIPEA990C55:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
MyVPCPublicSubnet3NATGateway7590C9CF:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- MyVPCPublicSubnet3EIPEA990C55
- AllocationId
SubnetId:
Ref: MyVPCPublicSubnet3Subnet1F5F6FC2
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PublicSubnet3
MyVPCPrivateSubnet1Subnet641543F4:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.96.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2a
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet1
MyVPCPrivateSubnet1RouteTable133BD901:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet1
MyVPCPrivateSubnet1RouteTableAssociation85DFBFBB:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet1RouteTable133BD901
SubnetId:
Ref: MyVPCPrivateSubnet1Subnet641543F4
MyVPCPrivateSubnet1DefaultRouteA8EE6636:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet1RouteTable133BD901
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: MyVPCPublicSubnet1NATGateway838228A5
MyVPCPrivateSubnet2SubnetA420D3F0:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.128.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2b
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet2
MyVPCPrivateSubnet2RouteTableDF3CB76C:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet2
MyVPCPrivateSubnet2RouteTableAssociationC373B6FE:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet2RouteTableDF3CB76C
SubnetId:
Ref: MyVPCPrivateSubnet2SubnetA420D3F0
MyVPCPrivateSubnet2DefaultRoute37F90B5D:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet2RouteTableDF3CB76C
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: MyVPCPublicSubnet2NATGateway4D6E78B8
MyVPCPrivateSubnet3SubnetE1B8B1B4:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.160.0/19
VpcId:
Ref: MyVPCAFB07A31
AvailabilityZone: us-west-2c
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet3
MyVPCPrivateSubnet3RouteTableC4FF197F:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: MyVPCAFB07A31
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC/PrivateSubnet3
MyVPCPrivateSubnet3RouteTableAssociation31B18386:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet3RouteTableC4FF197F
SubnetId:
Ref: MyVPCPrivateSubnet3SubnetE1B8B1B4
MyVPCPrivateSubnet3DefaultRouteE65E8A8F:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: MyVPCPrivateSubnet3RouteTableC4FF197F
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: MyVPCPublicSubnet3NATGateway7590C9CF
MyVPCIGW30AB6DD6:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
-
Key: Name
Value: app-with-vpc/MyVPC
MyVPCVPCGWE6F260E1:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId:
Ref: MyVPCAFB07A31
InternetGatewayId:
Ref: MyVPCIGW30AB6DD6
ExampleASGInstanceSecurityGroup57423FC2:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: app-with-vpc/ExampleASG/InstanceSecurityGroup
SecurityGroupEgress:
-
CidrIp: 0.0.0.0/0
Description: Allow all outbound traffic by default
IpProtocol: '-1'
SecurityGroupIngress: []
Tags:
-
Key: Name
Value: app-with-vpc/ExampleASG
VpcId:
Ref: MyVPCAFB07A31
ExampleASGInstanceSecurityGroupfromappwithvpcLBSecurityGroup451C8F6C80BB3EACE2:
Type: 'AWS::EC2::SecurityGroupIngress'
Properties:
IpProtocol: tcp
Description: Port 80 LB to fleet
FromPort: 80
GroupId:
'Fn::GetAtt':
- ExampleASGInstanceSecurityGroup57423FC2
- GroupId
SourceSecurityGroupId:
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
ToPort: 80
ExampleASGInstanceRole1F5D9A6B:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
-
Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Version: '2012-10-17'
ExampleASGInstanceProfileD70200DE:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
-
Ref: ExampleASGInstanceRole1F5D9A6B
ExampleASGLaunchConfig020480C8:
Type: 'AWS::AutoScaling::LaunchConfiguration'
Properties:
ImageId: ami-a0cfeed8
InstanceType: t2.small
IamInstanceProfile:
Ref: ExampleASGInstanceProfileD70200DE
SecurityGroups:
-
'Fn::GetAtt':
- ExampleASGInstanceSecurityGroup57423FC2
- GroupId
UserData:
'Fn::Base64': |
#!/bin/bash
DependsOn:
- ExampleASGInstanceRole1F5D9A6B
ExampleASG61DF90B6:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
MaxSize: '1'
MinSize: '1'
DesiredCapacity: '1'
LaunchConfigurationName:
Ref: ExampleASGLaunchConfig020480C8
LoadBalancerNames:
-
Ref: LB8A12904C
Tags:
-
Key: Name
PropagateAtLaunch: true
Value: app-with-vpc/ExampleASG
VPCZoneIdentifier:
-
Ref: MyVPCPrivateSubnet1Subnet641543F4
-
Ref: MyVPCPrivateSubnet2SubnetA420D3F0
-
Ref: MyVPCPrivateSubnet3SubnetE1B8B1B4
UpdatePolicy:
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: true
LBSecurityGroup8A41EA2B:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: app-with-vpc/LB/SecurityGroup
SecurityGroupEgress: []
SecurityGroupIngress:
-
CidrIp: 0.0.0.0/0
Description: Default rule allow on 80
FromPort: 80
IpProtocol: tcp
ToPort: 80
VpcId:
Ref: MyVPCAFB07A31
LBSecurityGrouptoappwithvpcExampleASGInstanceSecurityGroup4481B23A80C5F0238E:
Type: 'AWS::EC2::SecurityGroupEgress'
Properties:
GroupId:
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
IpProtocol: tcp
Description: Port 80 LB to fleet
DestinationSecurityGroupId:
'Fn::GetAtt':
- ExampleASGInstanceSecurityGroup57423FC2
- GroupId
FromPort: 80
ToPort: 80
LB8A12904C:
Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
Properties:
Listeners:
-
InstancePort: '80'
InstanceProtocol: http
LoadBalancerPort: '80'
Protocol: http
Scheme: internet-facing
SecurityGroups:
-
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
Subnets:
-
Ref: MyVPCPublicSubnet1Subnet0C75866A
-
Ref: MyVPCPublicSubnet2Subnet4DDFF14C
-
Ref: MyVPCPublicSubnet3Subnet1F5F6FC2
CDKMetadata:
Type: 'AWS::CDK::Metadata'
Properties:
Modules: >-
@aws-cdk/aws-autoscaling=0.14.1,@aws-cdk/aws-codedeploy-api=0.14.1,@aws-cdk/aws-ec2=0.14.1,@aws-cdk/aws-elasticloadbalancing=0.14.1,@aws-cdk/aws-elasticloadbalancingv2=0.14.1,@aws-cdk/aws-iam=0.14.1,@aws-cdk/cdk=0.14.1,@aws-cdk/cx-api=0.14.1,cdk=0.1.0
Nested Stackで作成する
続いてVPCとApplicationを分割したものを作ります。
VPCレイヤのスタックを作成する
まずVPCのスタックを定義します。
#!/usr/bin/env node
import ec2 = require('@aws-cdk/aws-ec2');
import autoscaling = require('@aws-cdk/aws-autoscaling');
import elb = require('@aws-cdk/aws-elasticloadbalancing')
import cdk = require('@aws-cdk/cdk');
// VPCネットワークのスタック
class CommonInfrastructure extends cdk.Stack {
public vpc: ec2.VpcNetworkRefProps;
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
super(parent, name, props)
// VPCを作成
const vpc = new ec2.VpcNetwork(this, 'VPC')
// 作成した情報をexportする
this.vpc = vpc.export()
}
}
Applicationレイヤのスタックを作成する
続いてApplicationのスタックを定義します。
// ↑ VPC Stack data
// Application側にインポートするための型定義
interface MyAppProps extends cdk.StackProps {
infra: CommonInfrastructure
}
// Applicationのスタック
class MyApp extends cdk.Stack {
constructor(parent: cdk.App, name: string, props: MyAppProps) {
super(parent, name, props)
// VPCのスタック情報をインポート
const vpc = ec2.VpcNetwork.import(this, 'VPC', props.infra.vpc)
// AutoScalingグループを作成
const fleet = new autoscaling.AutoScalingGroup(this, 'MyASG', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.T2, ec2.InstanceSize.Micro),
machineImage: new ec2.AmazonLinuxImage()
})
// Classic Load Balancerを作成
const clb = new elb.LoadBalancer(this, 'LB', {
vpc,
internetFacing: true
})
clb.addListener({ externalPort: 80})
clb.addTarget(fleet)
}
}
VPCとApplicationをつなげる
最後にそれぞれで作成したスタックを連携させます。
// ↑ VPC/Application Stack data
// 'infra'という名前でスタックのインスタンスを立ち上げ
const infra = new CommonInfrastructure(app, 'infra')
// Applicationスタックのインスタンスを立ち上げ。
// ここでVPCのスタックを引数として渡す
new MyApp(app, 'my-app', {
infra
})
app.run()
CloudFormationにExport
Nested StackをExportするときは、---output
オプションが必須です。
$ npm run build
$ cdk synth --output ./test
./test/infra.template.yaml
./test/my-app.template.yaml
infra.template.yml
Resources:
VPCB9E5F0B4:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
-
Key: Name
Value: infra/VPC
VPCPublicSubnet1SubnetB4246D30:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.0.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2a
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet1
VPCPublicSubnet1RouteTableFEE4B781:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet1
VPCPublicSubnet1RouteTableAssociation0B0896DC:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPublicSubnet1RouteTableFEE4B781
SubnetId:
Ref: VPCPublicSubnet1SubnetB4246D30
VPCPublicSubnet1DefaultRoute91CEF279:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPublicSubnet1RouteTableFEE4B781
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: VPCIGWB7E252D3
VPCPublicSubnet1EIP6AD938E8:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
VPCPublicSubnet1NATGatewayE0556630:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- VPCPublicSubnet1EIP6AD938E8
- AllocationId
SubnetId:
Ref: VPCPublicSubnet1SubnetB4246D30
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet1
VPCPublicSubnet2Subnet74179F39:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.32.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2b
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet2
VPCPublicSubnet2RouteTable6F1A15F1:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet2
VPCPublicSubnet2RouteTableAssociation5A808732:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPublicSubnet2RouteTable6F1A15F1
SubnetId:
Ref: VPCPublicSubnet2Subnet74179F39
VPCPublicSubnet2DefaultRouteB7481BBA:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPublicSubnet2RouteTable6F1A15F1
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: VPCIGWB7E252D3
VPCPublicSubnet2EIP4947BC00:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
VPCPublicSubnet2NATGateway3C070193:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- VPCPublicSubnet2EIP4947BC00
- AllocationId
SubnetId:
Ref: VPCPublicSubnet2Subnet74179F39
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet2
VPCPublicSubnet3Subnet631C5E25:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.64.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2c
MapPublicIpOnLaunch: true
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet3
VPCPublicSubnet3RouteTable98AE0E14:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet3
VPCPublicSubnet3RouteTableAssociation427FE0C6:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPublicSubnet3RouteTable98AE0E14
SubnetId:
Ref: VPCPublicSubnet3Subnet631C5E25
VPCPublicSubnet3DefaultRouteA0D29D46:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPublicSubnet3RouteTable98AE0E14
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: VPCIGWB7E252D3
VPCPublicSubnet3EIPAD4BC883:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
VPCPublicSubnet3NATGatewayD3048F5C:
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId:
'Fn::GetAtt':
- VPCPublicSubnet3EIPAD4BC883
- AllocationId
SubnetId:
Ref: VPCPublicSubnet3Subnet631C5E25
Tags:
-
Key: Name
Value: infra/VPC/PublicSubnet3
VPCPrivateSubnet1Subnet8BCA10E0:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.96.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2a
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet1
VPCPrivateSubnet1RouteTableBE8A6027:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet1
VPCPrivateSubnet1RouteTableAssociation347902D1:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet1RouteTableBE8A6027
SubnetId:
Ref: VPCPrivateSubnet1Subnet8BCA10E0
VPCPrivateSubnet1DefaultRouteAE1D6490:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet1RouteTableBE8A6027
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: VPCPublicSubnet1NATGatewayE0556630
VPCPrivateSubnet2SubnetCFCDAA7A:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.128.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2b
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet2
VPCPrivateSubnet2RouteTable0A19E10E:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet2
VPCPrivateSubnet2RouteTableAssociation0C73D413:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet2RouteTable0A19E10E
SubnetId:
Ref: VPCPrivateSubnet2SubnetCFCDAA7A
VPCPrivateSubnet2DefaultRouteF4F5CFD2:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet2RouteTable0A19E10E
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: VPCPublicSubnet2NATGateway3C070193
VPCPrivateSubnet3Subnet3EDCD457:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: 10.0.160.0/19
VpcId:
Ref: VPCB9E5F0B4
AvailabilityZone: us-west-2c
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet3
VPCPrivateSubnet3RouteTable192186F8:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId:
Ref: VPCB9E5F0B4
Tags:
-
Key: Name
Value: infra/VPC/PrivateSubnet3
VPCPrivateSubnet3RouteTableAssociationC28D144E:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet3RouteTable192186F8
SubnetId:
Ref: VPCPrivateSubnet3Subnet3EDCD457
VPCPrivateSubnet3DefaultRoute27F311AE:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId:
Ref: VPCPrivateSubnet3RouteTable192186F8
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: VPCPublicSubnet3NATGatewayD3048F5C
VPCIGWB7E252D3:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
-
Key: Name
Value: infra/VPC
VPCVPCGW99B986DC:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId:
Ref: VPCB9E5F0B4
InternetGatewayId:
Ref: VPCIGWB7E252D3
CDKMetadata:
Type: 'AWS::CDK::Metadata'
Properties:
Modules: >-
@aws-cdk/aws-autoscaling=0.14.1,@aws-cdk/aws-codedeploy-api=0.14.1,@aws-cdk/aws-ec2=0.14.1,@aws-cdk/aws-elasticloadbalancing=0.14.1,@aws-cdk/aws-elasticloadbalancingv2=0.14.1,@aws-cdk/aws-iam=0.14.1,@aws-cdk/cdk=0.14.1,@aws-cdk/cx-api=0.14.1,cdk=0.1.0
Outputs:
VPCPublicSubnetIDs428979F9:
Value:
'Fn::Join':
- ','
-
-
Ref: VPCPublicSubnet1SubnetB4246D30
-
Ref: VPCPublicSubnet2Subnet74179F39
-
Ref: VPCPublicSubnet3Subnet631C5E25
Export:
Name: 'infra:VPCPublicSubnetIDs428979F9'
VPCPrivateSubnetIDsA55EE406:
Value:
'Fn::Join':
- ','
-
-
Ref: VPCPrivateSubnet1Subnet8BCA10E0
-
Ref: VPCPrivateSubnet2SubnetCFCDAA7A
-
Ref: VPCPrivateSubnet3Subnet3EDCD457
Export:
Name: 'infra:VPCPrivateSubnetIDsA55EE406'
VPCVpcId2F75874A:
Value:
Ref: VPCB9E5F0B4
Export:
Name: 'infra:VPCVpcId2F75874A'
my-app.template.yml
Resources:
MyASGInstanceSecurityGroupBF55119F:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: my-app/MyASG/InstanceSecurityGroup
SecurityGroupEgress:
-
CidrIp: 0.0.0.0/0
Description: Allow all outbound traffic by default
IpProtocol: '-1'
SecurityGroupIngress: []
Tags:
-
Key: Name
Value: my-app/MyASG
VpcId:
'Fn::ImportValue': 'infra:VPCVpcId2F75874A'
MyASGInstanceSecurityGroupfrommyappLBSecurityGroupFC6760E08066F1683E:
Type: 'AWS::EC2::SecurityGroupIngress'
Properties:
IpProtocol: tcp
Description: Port 80 LB to fleet
FromPort: 80
GroupId:
'Fn::GetAtt':
- MyASGInstanceSecurityGroupBF55119F
- GroupId
SourceSecurityGroupId:
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
ToPort: 80
MyASGInstanceRoleE40FF11D:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
-
Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Version: '2012-10-17'
MyASGInstanceProfile2A2CDB5D:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
-
Ref: MyASGInstanceRoleE40FF11D
MyASGLaunchConfig075E9F95:
Type: 'AWS::AutoScaling::LaunchConfiguration'
Properties:
ImageId: ami-a0cfeed8
InstanceType: t2.micro
IamInstanceProfile:
Ref: MyASGInstanceProfile2A2CDB5D
SecurityGroups:
-
'Fn::GetAtt':
- MyASGInstanceSecurityGroupBF55119F
- GroupId
UserData:
'Fn::Base64': |
#!/bin/bash
DependsOn:
- MyASGInstanceRoleE40FF11D
MyASG63588E97:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
MaxSize: '1'
MinSize: '1'
DesiredCapacity: '1'
LaunchConfigurationName:
Ref: MyASGLaunchConfig075E9F95
LoadBalancerNames:
-
Ref: LB8A12904C
Tags:
-
Key: Name
PropagateAtLaunch: true
Value: my-app/MyASG
VPCZoneIdentifier:
-
'Fn::Select':
- 0
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPrivateSubnetIDsA55EE406'
-
'Fn::Select':
- 1
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPrivateSubnetIDsA55EE406'
-
'Fn::Select':
- 2
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPrivateSubnetIDsA55EE406'
UpdatePolicy:
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: true
LBSecurityGroup8A41EA2B:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: my-app/LB/SecurityGroup
SecurityGroupEgress: []
SecurityGroupIngress:
-
CidrIp: 0.0.0.0/0
Description: Default rule allow on 80
FromPort: 80
IpProtocol: tcp
ToPort: 80
VpcId:
'Fn::ImportValue': 'infra:VPCVpcId2F75874A'
LBSecurityGrouptomyappMyASGInstanceSecurityGroupF7B2EE4D80FD563A93:
Type: 'AWS::EC2::SecurityGroupEgress'
Properties:
GroupId:
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
IpProtocol: tcp
Description: Port 80 LB to fleet
DestinationSecurityGroupId:
'Fn::GetAtt':
- MyASGInstanceSecurityGroupBF55119F
- GroupId
FromPort: 80
ToPort: 80
LB8A12904C:
Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
Properties:
Listeners:
-
InstancePort: '80'
InstanceProtocol: http
LoadBalancerPort: '80'
Protocol: http
Scheme: internet-facing
SecurityGroups:
-
'Fn::GetAtt':
- LBSecurityGroup8A41EA2B
- GroupId
Subnets:
-
'Fn::Select':
- 0
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPublicSubnetIDs428979F9'
-
'Fn::Select':
- 1
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPublicSubnetIDs428979F9'
-
'Fn::Select':
- 2
-
'Fn::Split':
- ','
-
'Fn::ImportValue': 'infra:VPCPublicSubnetIDs428979F9'
CDKMetadata:
Type: 'AWS::CDK::Metadata'
Properties:
Modules: >-
@aws-cdk/aws-autoscaling=0.14.1,@aws-cdk/aws-codedeploy-api=0.14.1,@aws-cdk/aws-ec2=0.14.1,@aws-cdk/aws-elasticloadbalancing=0.14.1,@aws-cdk/aws-elasticloadbalancingv2=0.14.1,@aws-cdk/aws-iam=0.14.1,@aws-cdk/cdk=0.14.1,@aws-cdk/cx-api=0.14.1,cdk=0.1.0
まとめ
Nested Stackも1ファイルで完結させれるのは結構便利そうですね。
TypeScriptなので、必要な値が漏れていてもビルド時にエラーが出るのが助かりそうです。CloudFormationがRollbackするのを呆然と眺める時間が減りそうな予感がします。
ただしCloudFormationやterraform・ Serverless Frameworkでのリソース管理に慣れている方(というか自分)にはこの記法に馴染むのに少し時間がかかりそうかなという気もします。
まぁ、触って覚えるしかないですね。