(メモ) AWS CDK Pythonサンプルお試し

まだGAではないですがAWS CDKがPython対応したのでサンプルを動かしながらメモ。
CDKサンプルは他言語も含めてここにあります。
https://github.com/aws-samples/aws-cdk-examples

### 動かしたサンプル
ECS Service on EC2 with ALBのサンプルアプリケーション
https://github.com/aws-samples/aws-cdk-examples/tree/master/python/ecs/ecs-load-balanced-service/

**app.py**
リソースが記述された本体ファイル。これだけの記述。

```python:app.py
from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    cdk,
)


class BonjourECS(cdk.Stack):

    def __init__(self, scope: cdk.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, *kwargs)

        vpc = ec2.VpcNetwork(
            self, "MyVpc",
            max_a_zs=2
        )

        cluster = ecs.Cluster(
            self, 'Ec2Cluster',
            vpc=vpc
        )

        cluster.add_capacity("DefaultAutoScalingGroup",
                             instance_type=ec2.InstanceType("t2.micro"))

        ecs_service = ecs.LoadBalancedEc2Service(
            self, "Ec2Service",
            cluster=cluster,
            memory_limit_mi_b=512,
            image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")
        )

        cdk.CfnOutput(
            self, "LoadBalancerDNS",
            value=ecs_service.load_balancer.dns_name
        )

app = cdk.App()
BonjourECS(app, "Bonjour")
app.run()
```

**cdk.json**
CDKがどのランタイムとコードでスタックを作成するかを指定するファイル

```json:cdk.json
{
    "app": "python3 app.py"
}
```

**requirements.txt**
必要なライブラリ

```:requirements.txt
aws-cdk.cdk
aws-cdk.aws_ec2
aws-cdk.aws_ecs

# Work around for jsii#413
aws-cdk.aws-autoscaling-common
```

### デプロイ手順

PyCharm CE 2018.3 on MacOS Sierra(古...)上で作業しています

#### コードのclone

```sh:コマンド
sudo git clone https://github.com/aws-samples/aws-cdk-examples.git
cd aws-cdk-examples/python/ecs/ecs-load-balanced-service/
```

#### aws cdk インストール/アップデート

```sh:コマンド
sudo npm -g install aws-cdk
cdk --version
0.30.0 (build 4740446)
```

#### ライブラリインストール

```sh:コマンド
pip install -r requirements.txt
```

#### リソースの差分確認 (オプション)
cdk diffでリソースの差分確認を実施します。初期構築なので全てのリソースが追加差分として表示されます。
セキュリティ関連の変更をわかりやすく表示してくれるようになっていました。
＊これ以降はAWSクレデンシャルとデフォルトリージョンが設定されていないとエラーになります。

```sh:コマンド
cdk diff
```

```:Output
Stack Bonjour
IAM Statement Changes
┌───┬─────────────────────────────────────────┬────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬───────────────────────────────────────────┐
│   │ Resource                                │ Effect │ Action                                  │ Principal                               │ Condition                                 │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ lambda:InvokeFunction                   │ Service:sns.amazonaws.com               │ "ArnLike": {                              │
│   │ ainECSHook/Function.Arn}                │        │                                         │                                         │   "AWS:SourceArn": "${Ec2Cluster/DefaultA │
│   │                                         │        │                                         │                                         │ utoScalingGroup/DrainECSHook/Topic}"      │
│   │                                         │        │                                         │                                         │ }                                         │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ sts:AssumeRole                          │ Service:lambda.${AWS::URLSuffix}        │                                           │
│   │ ainECSHook/Function/ServiceRole.Arn}    │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ sns:Publish                             │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │ ainECSHook/Topic}                       │        │                                         │ p/LifecycleHookDrainHook/Role}          │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/In │ Allow  │ sts:AssumeRole                          │ Service:ec2.${AWS::URLSuffix}           │                                           │
│   │ stanceRole.Arn}                         │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Li │ Allow  │ sts:AssumeRole                          │ Service:autoscaling.${AWS::URLSuffix}   │                                           │
│   │ fecycleHookDrainHook/Role.Arn}          │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Service/TaskDef/TaskRole.Arn}      │ Allow  │ sts:AssumeRole                          │ Service:ecs-tasks.${AWS::URLSuffix}     │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ *                                       │ Allow  │ ecr:GetAuthorizationToken               │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ecs:CreateCluster                       │ p/InstanceRole}                         │                                           │
│   │                                         │        │ ecs:DeregisterContainerInstance         │                                         │                                           │
│   │                                         │        │ ecs:DiscoverPollEndpoint                │                                         │                                           │
│   │                                         │        │ ecs:Poll                                │                                         │                                           │
│   │                                         │        │ ecs:RegisterContainerInstance           │                                         │                                           │
│   │                                         │        │ ecs:StartTelemetrySession               │                                         │                                           │
│   │                                         │        │ ecs:Submit*                             │                                         │                                           │
│   │                                         │        │ logs:CreateLogStream                    │                                         │                                           │
│   │                                         │        │ logs:PutLogEvents                       │                                         │                                           │
│ + │ *                                       │ Allow  │ autoscaling:CompleteLifecycleAction     │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ec2:DescribeHosts                       │ p/DrainECSHook/Function/ServiceRole}    │                                           │
│   │                                         │        │ ec2:DescribeInstanceAttribute           │                                         │                                           │
│   │                                         │        │ ec2:DescribeInstanceStatus              │                                         │                                           │
│   │                                         │        │ ec2:DescribeInstances                   │                                         │                                           │
│ + │ *                                       │ Allow  │ ecs:DescribeContainerInstances          │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ecs:DescribeTasks                       │ p/DrainECSHook/Function/ServiceRole}    │                                           │
│   │                                         │        │ ecs:ListContainerInstances              │                                         │                                           │
│   │                                         │        │ ecs:ListTasks                           │                                         │                                           │
│   │                                         │        │ ecs:SubmitContainerStateChange          │                                         │                                           │
│   │                                         │        │ ecs:SubmitTaskStateChange               │                                         │                                           │
│   │                                         │        │ ecs:UpdateContainerInstancesState       │                                         │                                           │
└───┴─────────────────────────────────────────┴────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴───────────────────────────────────────────┘
IAM Policy Changes
┌───┬─────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                                                                │ Managed Policy ARN                                                             │
├───┼─────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
Security Group Changes
┌───┬─────────────────────────────────────────────────────────────────────┬─────┬─────────────────┬─────────────────────────────────────────────────────────────────────┐
│   │ Group                                                               │ Dir │ Protocol        │ Peer                                                                │
├───┼─────────────────────────────────────────────────────────────────────┼─────┼─────────────────┼─────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │ In  │ TCP 32768-65535 │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │ Out │ Everything      │ Everyone (IPv4)                                                     │
├───┼─────────────────────────────────────────────────────────────────────┼─────┼─────────────────┼─────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │ In  │ TCP 80          │ Everyone (IPv4)                                                     │
│ + │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │ Out │ TCP 32768-65535 │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │
└───┴─────────────────────────────────────────────────────────────────────┴─────┴─────────────────┴─────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See http://bit.ly/cdk-2EhF7Np)

Resources
[+] AWS::EC2::VPC MyVpc MyVpcF9F0CA6F 
[+] AWS::EC2::Subnet MyVpc/PublicSubnet1/Subnet MyVpcPublicSubnet1SubnetF6608456 
[+] AWS::EC2::RouteTable MyVpc/PublicSubnet1/RouteTable MyVpcPublicSubnet1RouteTableC46AB2F4 
[+] AWS::EC2::SubnetRouteTableAssociation MyVpc/PublicSubnet1/RouteTableAssociation MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB 
[+] AWS::EC2::Route MyVpc/PublicSubnet1/DefaultRoute MyVpcPublicSubnet1DefaultRoute95FDF9EB 
[+] AWS::EC2::EIP MyVpc/PublicSubnet1/EIP MyVpcPublicSubnet1EIP096967CB 
[+] AWS::EC2::NatGateway MyVpc/PublicSubnet1/NATGateway MyVpcPublicSubnet1NATGatewayAD3400C1 
[+] AWS::EC2::Subnet MyVpc/PublicSubnet2/Subnet MyVpcPublicSubnet2Subnet492B6BFB 
[+] AWS::EC2::RouteTable MyVpc/PublicSubnet2/RouteTable MyVpcPublicSubnet2RouteTable1DF17386 
[+] AWS::EC2::SubnetRouteTableAssociation MyVpc/PublicSubnet2/RouteTableAssociation MyVpcPublicSubnet2RouteTableAssociation227DE78D 
[+] AWS::EC2::Route MyVpc/PublicSubnet2/DefaultRoute MyVpcPublicSubnet2DefaultRoute052936F6 
[+] AWS::EC2::EIP MyVpc/PublicSubnet2/EIP MyVpcPublicSubnet2EIP8CCBA239 
[+] AWS::EC2::NatGateway MyVpc/PublicSubnet2/NATGateway MyVpcPublicSubnet2NATGateway91BFBEC9 
[+] AWS::EC2::Subnet MyVpc/PrivateSubnet1/Subnet MyVpcPrivateSubnet1Subnet5057CF7E 
[+] AWS::EC2::RouteTable MyVpc/PrivateSubnet1/RouteTable MyVpcPrivateSubnet1RouteTable8819E6E2 
[+] AWS::EC2::SubnetRouteTableAssociation MyVpc/PrivateSubnet1/RouteTableAssociation MyVpcPrivateSubnet1RouteTableAssociation56D38C7E 
[+] AWS::EC2::Route MyVpc/PrivateSubnet1/DefaultRoute MyVpcPrivateSubnet1DefaultRouteA8CDE2FA 
[+] AWS::EC2::Subnet MyVpc/PrivateSubnet2/Subnet MyVpcPrivateSubnet2Subnet0040C983 
[+] AWS::EC2::RouteTable MyVpc/PrivateSubnet2/RouteTable MyVpcPrivateSubnet2RouteTableCEDCEECE 
[+] AWS::EC2::SubnetRouteTableAssociation MyVpc/PrivateSubnet2/RouteTableAssociation MyVpcPrivateSubnet2RouteTableAssociation86A610DA 
[+] AWS::EC2::Route MyVpc/PrivateSubnet2/DefaultRoute MyVpcPrivateSubnet2DefaultRoute9CE96294 
[+] AWS::EC2::InternetGateway MyVpc/IGW MyVpcIGW5C4A4F63 
[+] AWS::EC2::VPCGatewayAttachment MyVpc/VPCGW MyVpcVPCGW488ACE0D 
[+] AWS::ECS::Cluster Ec2Cluster Ec2ClusterEE43E89D 
[+] AWS::EC2::SecurityGroup Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E 
[+] AWS::EC2::SecurityGroupIngress Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup/from BonjourEc2ServiceLBSecurityGroup2185A60D:32768-65535 Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroupfromBonjourEc2ServiceLBSecurityGroup2185A60D3276865535EC4EE766 
[+] AWS::IAM::Role Ec2Cluster/DefaultAutoScalingGroup/InstanceRole Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898 
[+] AWS::IAM::Policy Ec2Cluster/DefaultAutoScalingGroup/InstanceRole/DefaultPolicy Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD 
[+] AWS::IAM::InstanceProfile Ec2Cluster/DefaultAutoScalingGroup/InstanceProfile Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471 
[+] AWS::AutoScaling::LaunchConfiguration Ec2Cluster/DefaultAutoScalingGroup/LaunchConfig Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A 
[+] AWS::AutoScaling::AutoScalingGroup Ec2Cluster/DefaultAutoScalingGroup/ASG Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0 
[+] AWS::SNS::Topic Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Topic Ec2ClusterDefaultAutoScalingGroupDrainECSHookTopic798CDC5F 
[+] AWS::IAM::Role Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3 
[+] AWS::IAM::Policy Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole/DefaultPolicy Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33 
[+] AWS::Lambda::Function Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31 
[+] AWS::SNS::Subscription Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/TopicSubscription Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscription5DE5A98D 
[+] AWS::Lambda::Permission Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/Topic Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic6C30136B 
[+] AWS::IAM::Role Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7 
[+] AWS::IAM::Policy Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role/DefaultPolicy Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B 
[+] AWS::AutoScaling::LifecycleHook Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHook5CB1467E 
[+] AWS::ElasticLoadBalancingV2::LoadBalancer Ec2Service/LB Ec2ServiceLB381329CE 
[+] AWS::EC2::SecurityGroup Ec2Service/LB/SecurityGroup Ec2ServiceLBSecurityGroup45FED6DF 
[+] AWS::EC2::SecurityGroupEgress Ec2Service/LB/SecurityGroup/to BonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF5:32768-65535 Ec2ServiceLBSecurityGrouptoBonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF53276865535AC4204BB 
[+] AWS::ElasticLoadBalancingV2::Listener Ec2Service/LB/PublicListener Ec2ServiceLBPublicListenerA941070C 
[+] AWS::ElasticLoadBalancingV2::TargetGroup Ec2Service/LB/PublicListener/ECSGroup Ec2ServiceLBPublicListenerECSGroup3DC8690E 
[+] AWS::IAM::Role Ec2Service/TaskDef/TaskRole Ec2ServiceTaskDefTaskRole27A5D642 
[+] AWS::ECS::TaskDefinition Ec2Service/TaskDef Ec2ServiceTaskDef8D94BAA3 
[+] AWS::ECS::Service Ec2Service/Service/Service Ec2Service398F0E46 

Outputs
[+] Output Ec2Service/LoadBalancerDNS Ec2ServiceLoadBalancerDNS6983C9B2: {"Value":{"Fn::GetAtt":["Ec2ServiceLB381329CE","DNSName"]}}
[+] Output LoadBalancerDNS LoadBalancerDNS: {"Value":{"Fn::GetAtt":["Ec2ServiceLB381329CE","DNSName"]}}
```

### CloudFormationテンプレート確認 (オプション)
cdk synthコマンドで実際に展開されるCloudFormationテンプレートのResourcesを確認できます。

```sh:コマンド
cdk synth
```

```yaml:Output
 MyVpcF9F0CA6F:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: Bonjour/MyVpc
    Metadata:
      aws:cdk:path: Bonjour/MyVpc/Resource
  MyVpcPublicSubnet1SubnetF6608456:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/18
      VpcId:
        Ref: MyVpcF9F0CA6F
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: Bonjour/MyVpc/PublicSubnet1
        - Key: aws-cdk:subnet-name
          Value: Public
        - Key: aws-cdk:subnet-type
          Value: Public
<...snip...>
```
長いので省略。792行ありました。CDKを使うとCloudFormationを生で書くより記述量を削減できることがわかります。

#### デプロイ
cdk deployでデプロイします。

```sh:コマンド
cdk deploy
```

```:Output
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬─────────────────────────────────────────┬────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬───────────────────────────────────────────┐
│   │ Resource                                │ Effect │ Action                                  │ Principal                               │ Condition                                 │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ lambda:InvokeFunction                   │ Service:sns.amazonaws.com               │ "ArnLike": {                              │
│   │ ainECSHook/Function.Arn}                │        │                                         │                                         │   "AWS:SourceArn": "${Ec2Cluster/DefaultA │
│   │                                         │        │                                         │                                         │ utoScalingGroup/DrainECSHook/Topic}"      │
│   │                                         │        │                                         │                                         │ }                                         │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ sts:AssumeRole                          │ Service:lambda.${AWS::URLSuffix}        │                                           │
│   │ ainECSHook/Function/ServiceRole.Arn}    │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Dr │ Allow  │ sns:Publish                             │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │ ainECSHook/Topic}                       │        │                                         │ p/LifecycleHookDrainHook/Role}          │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/In │ Allow  │ sts:AssumeRole                          │ Service:ec2.${AWS::URLSuffix}           │                                           │
│   │ stanceRole.Arn}                         │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/Li │ Allow  │ sts:AssumeRole                          │ Service:autoscaling.${AWS::URLSuffix}   │                                           │
│   │ fecycleHookDrainHook/Role.Arn}          │        │                                         │                                         │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ ${Ec2Service/TaskDef/TaskRole.Arn}      │ Allow  │ sts:AssumeRole                          │ Service:ecs-tasks.${AWS::URLSuffix}     │                                           │
├───┼─────────────────────────────────────────┼────────┼─────────────────────────────────────────┼─────────────────────────────────────────┼───────────────────────────────────────────┤
│ + │ *                                       │ Allow  │ ecr:GetAuthorizationToken               │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ecs:CreateCluster                       │ p/InstanceRole}                         │                                           │
│   │                                         │        │ ecs:DeregisterContainerInstance         │                                         │                                           │
│   │                                         │        │ ecs:DiscoverPollEndpoint                │                                         │                                           │
│   │                                         │        │ ecs:Poll                                │                                         │                                           │
│   │                                         │        │ ecs:RegisterContainerInstance           │                                         │                                           │
│   │                                         │        │ ecs:StartTelemetrySession               │                                         │                                           │
│   │                                         │        │ ecs:Submit*                             │                                         │                                           │
│   │                                         │        │ logs:CreateLogStream                    │                                         │                                           │
│   │                                         │        │ logs:PutLogEvents                       │                                         │                                           │
│ + │ *                                       │ Allow  │ autoscaling:CompleteLifecycleAction     │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ec2:DescribeHosts                       │ p/DrainECSHook/Function/ServiceRole}    │                                           │
│   │                                         │        │ ec2:DescribeInstanceAttribute           │                                         │                                           │
│   │                                         │        │ ec2:DescribeInstanceStatus              │                                         │                                           │
│   │                                         │        │ ec2:DescribeInstances                   │                                         │                                           │
│ + │ *                                       │ Allow  │ ecs:DescribeContainerInstances          │ AWS:${Ec2Cluster/DefaultAutoScalingGrou │                                           │
│   │                                         │        │ ecs:DescribeTasks                       │ p/DrainECSHook/Function/ServiceRole}    │                                           │
│   │                                         │        │ ecs:ListContainerInstances              │                                         │                                           │
│   │                                         │        │ ecs:ListTasks                           │                                         │                                           │
│   │                                         │        │ ecs:SubmitContainerStateChange          │                                         │                                           │
│   │                                         │        │ ecs:SubmitTaskStateChange               │                                         │                                           │
│   │                                         │        │ ecs:UpdateContainerInstancesState       │                                         │                                           │
└───┴─────────────────────────────────────────┴────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴───────────────────────────────────────────┘
IAM Policy Changes
┌───┬─────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                                                                │ Managed Policy ARN                                                             │
├───┼─────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
Security Group Changes
┌───┬─────────────────────────────────────────────────────────────────────┬─────┬─────────────────┬─────────────────────────────────────────────────────────────────────┐
│   │ Group                                                               │ Dir │ Protocol        │ Peer                                                                │
├───┼─────────────────────────────────────────────────────────────────────┼─────┼─────────────────┼─────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │ In  │ TCP 32768-65535 │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │
│ + │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │ Out │ Everything      │ Everyone (IPv4)                                                     │
├───┼─────────────────────────────────────────────────────────────────────┼─────┼─────────────────┼─────────────────────────────────────────────────────────────────────┤
│ + │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │ In  │ TCP 80          │ Everyone (IPv4)                                                     │
│ + │ ${Ec2Service/LB/SecurityGroup.GroupId}                              │ Out │ TCP 32768-65535 │ ${Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup.GroupId} │
└───┴─────────────────────────────────────────────────────────────────────┴─────┴─────────────────┴─────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See http://bit.ly/cdk-2EhF7Np)
Bonjour: deploying...
Bonjour: creating CloudFormation changeset...
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                        | CDKMetadata 
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::SNS::Topic                           | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookTopic798CDC5F) 
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7) 
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Service/TaskDef/TaskRole (Ec2ServiceTaskDefTaskRole27A5D642) 
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3) 
  0/50 | 11:35:04 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole (Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::EC2::EIP                             | MyVpc/PublicSubnet1/EIP (MyVpcPublicSubnet1EIP096967CB) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::ECS::Cluster                         | Ec2Cluster (Ec2ClusterEE43E89D) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::EC2::VPC                             | MyVpc (MyVpcF9F0CA6F) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Service/TaskDef/TaskRole (Ec2ServiceTaskDefTaskRole27A5D642) Resource creation Initiated
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::SNS::Topic                           | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookTopic798CDC5F) Resource creation Initiated
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7) Resource creation Initiated
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::EC2::EIP                             | MyVpc/PublicSubnet2/EIP (MyVpcPublicSubnet2EIP8CCBA239) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::ECS::Cluster                         | Ec2Cluster (Ec2ClusterEE43E89D) Resource creation Initiated
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::EC2::InternetGateway                 | MyVpc/IGW (MyVpcIGW5C4A4F63) 
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::EC2::EIP                             | MyVpc/PublicSubnet1/EIP (MyVpcPublicSubnet1EIP096967CB) Resource creation Initiated
  0/50 | 11:35:05 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3) Resource creation Initiated
  0/50 | 11:35:06 AM | CREATE_IN_PROGRESS   | AWS::EC2::VPC                             | MyVpc (MyVpcF9F0CA6F) Resource creation Initiated
  1/50 | 11:35:06 AM | CREATE_COMPLETE      | AWS::ECS::Cluster                         | Ec2Cluster (Ec2ClusterEE43E89D) 
  1/50 | 11:35:06 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole (Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898) Resource creation Initiated
  1/50 | 11:35:06 AM | CREATE_IN_PROGRESS   | AWS::EC2::InternetGateway                 | MyVpc/IGW (MyVpcIGW5C4A4F63) Resource creation Initiated
  1/50 | 11:35:06 AM | CREATE_IN_PROGRESS   | AWS::EC2::EIP                             | MyVpc/PublicSubnet2/EIP (MyVpcPublicSubnet2EIP8CCBA239) Resource creation Initiated
  1/50 | 11:35:07 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                        | CDKMetadata Resource creation Initiated
  2/50 | 11:35:07 AM | CREATE_COMPLETE      | AWS::CDK::Metadata                        | CDKMetadata 
  3/50 | 11:35:16 AM | CREATE_COMPLETE      | AWS::SNS::Topic                           | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookTopic798CDC5F) 
  4/50 | 11:35:21 AM | CREATE_COMPLETE      | AWS::EC2::EIP                             | MyVpc/PublicSubnet1/EIP (MyVpcPublicSubnet1EIP096967CB) 
  5/50 | 11:35:22 AM | CREATE_COMPLETE      | AWS::EC2::EIP                             | MyVpc/PublicSubnet2/EIP (MyVpcPublicSubnet2EIP8CCBA239) 
  6/50 | 11:35:22 AM | CREATE_COMPLETE      | AWS::EC2::InternetGateway                 | MyVpc/IGW (MyVpcIGW5C4A4F63) 
  7/50 | 11:35:22 AM | CREATE_COMPLETE      | AWS::EC2::VPC                             | MyVpc (MyVpcF9F0CA6F) 
  8/50 | 11:35:23 AM | CREATE_COMPLETE      | AWS::IAM::Role                            | Ec2Service/TaskDef/TaskRole (Ec2ServiceTaskDefTaskRole27A5D642) 
  9/50 | 11:35:23 AM | CREATE_COMPLETE      | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRole71045ED7) 
 10/50 | 11:35:23 AM | CREATE_COMPLETE      | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRole23116FA3) 
 11/50 | 11:35:23 AM | CREATE_COMPLETE      | AWS::IAM::Role                            | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole (Ec2ClusterDefaultAutoScalingGroupInstanceRole73D80898) 
 11/50 | 11:35:26 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PublicSubnet2/Subnet (MyVpcPublicSubnet2Subnet492B6BFB) 
 11/50 | 11:35:26 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PublicSubnet1/Subnet (MyVpcPublicSubnet1SubnetF6608456) 
 11/50 | 11:35:26 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet1/RouteTable (MyVpcPublicSubnet1RouteTableC46AB2F4) 
 11/50 | 11:35:26 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet2/Subnet (MyVpcPrivateSubnet2Subnet0040C983) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup                   | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet2/RouteTable (MyVpcPrivateSubnet2RouteTableCEDCEECE) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet1/RouteTable (MyVpcPrivateSubnet1RouteTable8819E6E2) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup                   | Ec2Service/LB/SecurityGroup (Ec2ServiceLBSecurityGroup45FED6DF) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::TargetGroup  | Ec2Service/LB/PublicListener/ECSGroup (Ec2ServiceLBPublicListenerECSGroup3DC8690E) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet1/Subnet (MyVpcPrivateSubnet1Subnet5057CF7E) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PublicSubnet2/Subnet (MyVpcPublicSubnet2Subnet492B6BFB) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::VPCGatewayAttachment            | MyVpc/VPCGW (MyVpcVPCGW488ACE0D) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::IAM::InstanceProfile                 | Ec2Cluster/DefaultAutoScalingGroup/InstanceProfile (Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet2/RouteTable (MyVpcPrivateSubnet2RouteTableCEDCEECE) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet1/RouteTable (MyVpcPublicSubnet1RouteTableC46AB2F4) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PublicSubnet1/Subnet (MyVpcPublicSubnet1SubnetF6608456) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet2/Subnet (MyVpcPrivateSubnet2Subnet0040C983) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet1/RouteTable (MyVpcPrivateSubnet1RouteTable8819E6E2) Resource creation Initiated
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet2/RouteTable (MyVpcPublicSubnet2RouteTable1DF17386) 
 11/50 | 11:35:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::VPCGatewayAttachment            | MyVpc/VPCGW (MyVpcVPCGW488ACE0D) Resource creation Initiated
 11/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33) 
 11/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::TargetGroup  | Ec2Service/LB/PublicListener/ECSGroup (Ec2ServiceLBPublicListenerECSGroup3DC8690E) Resource creation Initiated
 11/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet1/Subnet (MyVpcPrivateSubnet1Subnet5057CF7E) Resource creation Initiated
 11/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::ECS::TaskDefinition                  | Ec2Service/TaskDef (Ec2ServiceTaskDef8D94BAA3) 
 12/50 | 11:35:28 AM | CREATE_COMPLETE      | AWS::ElasticLoadBalancingV2::TargetGroup  | Ec2Service/LB/PublicListener/ECSGroup (Ec2ServiceLBPublicListenerECSGroup3DC8690E) 
 12/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet2/RouteTable (MyVpcPublicSubnet2RouteTable1DF17386) Resource creation Initiated
 13/50 | 11:35:28 AM | CREATE_COMPLETE      | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet2/RouteTable (MyVpcPrivateSubnet2RouteTableCEDCEECE) 
 13/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::ECS::TaskDefinition                  | Ec2Service/TaskDef (Ec2ServiceTaskDef8D94BAA3) Resource creation Initiated
 14/50 | 11:35:28 AM | CREATE_COMPLETE      | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet1/RouteTable (MyVpcPublicSubnet1RouteTableC46AB2F4) 
 15/50 | 11:35:28 AM | CREATE_COMPLETE      | AWS::EC2::RouteTable                      | MyVpc/PrivateSubnet1/RouteTable (MyVpcPrivateSubnet1RouteTable8819E6E2) 
 15/50 | 11:35:28 AM | CREATE_IN_PROGRESS   | AWS::IAM::InstanceProfile                 | Ec2Cluster/DefaultAutoScalingGroup/InstanceProfile (Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471) Resource creation Initiated
 16/50 | 11:35:29 AM | CREATE_COMPLETE      | AWS::ECS::TaskDefinition                  | Ec2Service/TaskDef (Ec2ServiceTaskDef8D94BAA3) 
 16/50 | 11:35:29 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B) Resource creation Initiated
 16/50 | 11:35:29 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD) Resource creation Initiated
 17/50 | 11:35:29 AM | CREATE_COMPLETE      | AWS::EC2::RouteTable                      | MyVpc/PublicSubnet2/RouteTable (MyVpcPublicSubnet2RouteTable1DF17386) 
 17/50 | 11:35:30 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33) Resource creation Initiated
 17/50 | 11:35:32 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup                   | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E) Resource creation Initiated
 17/50 | 11:35:32 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup                   | Ec2Service/LB/SecurityGroup (Ec2ServiceLBSecurityGroup45FED6DF) Resource creation Initiated
 18/50 | 11:35:33 AM | CREATE_COMPLETE      | AWS::EC2::SecurityGroup                   | Ec2Service/LB/SecurityGroup (Ec2ServiceLBSecurityGroup45FED6DF) 
 19/50 | 11:35:34 AM | CREATE_COMPLETE      | AWS::EC2::SecurityGroup                   | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroup149B0A9E) 
 20/50 | 11:35:37 AM | CREATE_COMPLETE      | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook/Role/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHookRoleDefaultPolicyE499974B) 
 21/50 | 11:35:37 AM | CREATE_COMPLETE      | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/InstanceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupInstanceRoleDefaultPolicy6D2DC2FD) 
 21/50 | 11:35:38 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroupEgress             | Ec2Service/LB/SecurityGroup/to BonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF5:32768-65535 (Ec2ServiceLBSecurityGrouptoBonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF53276865535AC4204BB) 
 21/50 | 11:35:38 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroupIngress            | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup/from BonjourEc2ServiceLBSecurityGroup2185A60D:32768-65535 (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroupfromBonjourEc2ServiceLBSecurityGroup2185A60D3276865535EC4EE766) 
 22/50 | 11:35:38 AM | CREATE_COMPLETE      | AWS::IAM::Policy                          | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/ServiceRole/DefaultPolicy (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionServiceRoleDefaultPolicy638C9E33) 
 22/50 | 11:35:38 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroupIngress            | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup/from BonjourEc2ServiceLBSecurityGroup2185A60D:32768-65535 (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroupfromBonjourEc2ServiceLBSecurityGroup2185A60D3276865535EC4EE766) Resource creation Initiated
 22/50 | 11:35:38 AM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroupEgress             | Ec2Service/LB/SecurityGroup/to BonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF5:32768-65535 (Ec2ServiceLBSecurityGrouptoBonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF53276865535AC4204BB) Resource creation Initiated
 23/50 | 11:35:39 AM | CREATE_COMPLETE      | AWS::EC2::SecurityGroupIngress            | Ec2Cluster/DefaultAutoScalingGroup/InstanceSecurityGroup/from BonjourEc2ServiceLBSecurityGroup2185A60D:32768-65535 (Ec2ClusterDefaultAutoScalingGroupInstanceSecurityGroupfromBonjourEc2ServiceLBSecurityGroup2185A60D3276865535EC4EE766) 
 24/50 | 11:35:40 AM | CREATE_COMPLETE      | AWS::EC2::SecurityGroupEgress             | Ec2Service/LB/SecurityGroup/to BonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF5:32768-65535 (Ec2ServiceLBSecurityGrouptoBonjourEc2ClusterDefaultAutoScalingGroupInstanceSecurityGroupE49ADAF53276865535AC4204BB) 
 24/50 | 11:35:42 AM | CREATE_IN_PROGRESS   | AWS::Lambda::Function                     | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31) 
 25/50 | 11:35:43 AM | CREATE_COMPLETE      | AWS::EC2::VPCGatewayAttachment            | MyVpc/VPCGW (MyVpcVPCGW488ACE0D) 
 25/50 | 11:35:43 AM | CREATE_IN_PROGRESS   | AWS::Lambda::Function                     | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31) Resource creation Initiated
 26/50 | 11:35:44 AM | CREATE_COMPLETE      | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet2/Subnet (MyVpcPrivateSubnet2Subnet0040C983) 
 27/50 | 11:35:44 AM | CREATE_COMPLETE      | AWS::EC2::Subnet                          | MyVpc/PublicSubnet2/Subnet (MyVpcPublicSubnet2Subnet492B6BFB) 
 28/50 | 11:35:44 AM | CREATE_COMPLETE      | AWS::Lambda::Function                     | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionE0DEFB31) 
 29/50 | 11:35:44 AM | CREATE_COMPLETE      | AWS::EC2::Subnet                          | MyVpc/PublicSubnet1/Subnet (MyVpcPublicSubnet1SubnetF6608456) 
 30/50 | 11:35:44 AM | CREATE_COMPLETE      | AWS::EC2::Subnet                          | MyVpc/PrivateSubnet1/Subnet (MyVpcPrivateSubnet1Subnet5057CF7E) 
 30/50 | 11:35:47 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PublicSubnet2/DefaultRoute (MyVpcPublicSubnet2DefaultRoute052936F6) 
 30/50 | 11:35:47 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PublicSubnet1/DefaultRoute (MyVpcPublicSubnet1DefaultRoute95FDF9EB) 
 30/50 | 11:35:47 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet2/RouteTableAssociation (MyVpcPrivateSubnet2RouteTableAssociation86A610DA) 
 30/50 | 11:35:47 AM | CREATE_IN_PROGRESS   | AWS::SNS::Subscription                    | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/TopicSubscription (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscription5DE5A98D) 
 30/50 | 11:35:47 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PublicSubnet1/DefaultRoute (MyVpcPublicSubnet1DefaultRoute95FDF9EB) Resource creation Initiated
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet2/RouteTableAssociation (MyVpcPublicSubnet2RouteTableAssociation227DE78D) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PublicSubnet2/DefaultRoute (MyVpcPublicSubnet2DefaultRoute052936F6) Resource creation Initiated
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::Lambda::Permission                   | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic6C30136B) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet1/NATGateway (MyVpcPublicSubnet1NATGatewayAD3400C1) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet2/NATGateway (MyVpcPublicSubnet2NATGateway91BFBEC9) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet1/RouteTableAssociation (MyVpcPrivateSubnet1RouteTableAssociation56D38C7E) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet1/RouteTableAssociation (MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB) 
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::Lambda::Permission                   | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic6C30136B) Resource creation Initiated
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet2/RouteTableAssociation (MyVpcPrivateSubnet2RouteTableAssociation86A610DA) Resource creation Initiated
 30/50 | 11:35:48 AM | CREATE_IN_PROGRESS   | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet1/NATGateway (MyVpcPublicSubnet1NATGatewayAD3400C1) Resource creation Initiated
 30/50 | 11:35:49 AM | CREATE_IN_PROGRESS   | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet2/NATGateway (MyVpcPublicSubnet2NATGateway91BFBEC9) Resource creation Initiated
 30/50 | 11:35:49 AM | CREATE_IN_PROGRESS   | AWS::SNS::Subscription                    | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/TopicSubscription (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscription5DE5A98D) Resource creation Initiated
 31/50 | 11:35:49 AM | CREATE_COMPLETE      | AWS::SNS::Subscription                    | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/TopicSubscription (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscription5DE5A98D) 
 31/50 | 11:35:49 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet2/RouteTableAssociation (MyVpcPublicSubnet2RouteTableAssociation227DE78D) Resource creation Initiated
 31/50 | 11:35:49 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet1/RouteTableAssociation (MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB) Resource creation Initiated
 31/50 | 11:35:49 AM | CREATE_IN_PROGRESS   | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet1/RouteTableAssociation (MyVpcPrivateSubnet1RouteTableAssociation56D38C7E) Resource creation Initiated
 32/50 | 11:35:58 AM | CREATE_COMPLETE      | AWS::Lambda::Permission                   | Ec2Cluster/DefaultAutoScalingGroup/DrainECSHook/Function/Topic (Ec2ClusterDefaultAutoScalingGroupDrainECSHookFunctionTopic6C30136B) 
 33/50 | 11:36:03 AM | CREATE_COMPLETE      | AWS::EC2::Route                           | MyVpc/PublicSubnet1/DefaultRoute (MyVpcPublicSubnet1DefaultRoute95FDF9EB) 
 34/50 | 11:36:03 AM | CREATE_COMPLETE      | AWS::EC2::Route                           | MyVpc/PublicSubnet2/DefaultRoute (MyVpcPublicSubnet2DefaultRoute052936F6) 
 35/50 | 11:36:04 AM | CREATE_COMPLETE      | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet2/RouteTableAssociation (MyVpcPrivateSubnet2RouteTableAssociation86A610DA) 
 36/50 | 11:36:04 AM | CREATE_COMPLETE      | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet2/RouteTableAssociation (MyVpcPublicSubnet2RouteTableAssociation227DE78D) 
 37/50 | 11:36:05 AM | CREATE_COMPLETE      | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PublicSubnet1/RouteTableAssociation (MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB) 
 38/50 | 11:36:05 AM | CREATE_COMPLETE      | AWS::EC2::SubnetRouteTableAssociation     | MyVpc/PrivateSubnet1/RouteTableAssociation (MyVpcPrivateSubnet1RouteTableAssociation56D38C7E) 
 38/50 | 11:36:08 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::LoadBalancer | Ec2Service/LB (Ec2ServiceLB381329CE) 
 38/50 | 11:36:10 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::LoadBalancer | Ec2Service/LB (Ec2ServiceLB381329CE) Resource creation Initiated
38/50 Currently in progress: Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471, MyVpcPublicSubnet1NATGatewayAD3400C1, MyVpcPublicSubnet2NATGateway91BFBEC9, Ec2ServiceLB381329CE
 39/50 | 11:37:22 AM | CREATE_COMPLETE      | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet1/NATGateway (MyVpcPublicSubnet1NATGatewayAD3400C1) 
 39/50 | 11:37:26 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PrivateSubnet1/DefaultRoute (MyVpcPrivateSubnet1DefaultRouteA8CDE2FA) 
 39/50 | 11:37:27 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PrivateSubnet1/DefaultRoute (MyVpcPrivateSubnet1DefaultRouteA8CDE2FA) Resource creation Initiated
 40/50 | 11:37:30 AM | CREATE_COMPLETE      | AWS::IAM::InstanceProfile                 | Ec2Cluster/DefaultAutoScalingGroup/InstanceProfile (Ec2ClusterDefaultAutoScalingGroupInstanceProfileDB232471) 
 40/50 | 11:37:34 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::LaunchConfiguration     | Ec2Cluster/DefaultAutoScalingGroup/LaunchConfig (Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A) 
 40/50 | 11:37:35 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::LaunchConfiguration     | Ec2Cluster/DefaultAutoScalingGroup/LaunchConfig (Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A) Resource creation Initiated
 41/50 | 11:37:35 AM | CREATE_COMPLETE      | AWS::AutoScaling::LaunchConfiguration     | Ec2Cluster/DefaultAutoScalingGroup/LaunchConfig (Ec2ClusterDefaultAutoScalingGroupLaunchConfig7B2FED3A) 
 42/50 | 11:37:38 AM | CREATE_COMPLETE      | AWS::EC2::NatGateway                      | MyVpc/PublicSubnet2/NATGateway (MyVpcPublicSubnet2NATGateway91BFBEC9) 
 42/50 | 11:37:39 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::AutoScalingGroup        | Ec2Cluster/DefaultAutoScalingGroup/ASG (Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0) 
 42/50 | 11:37:41 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::AutoScalingGroup        | Ec2Cluster/DefaultAutoScalingGroup/ASG (Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0) Resource creation Initiated
 42/50 | 11:37:42 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PrivateSubnet2/DefaultRoute (MyVpcPrivateSubnet2DefaultRoute9CE96294) 
 43/50 | 11:37:43 AM | CREATE_COMPLETE      | AWS::EC2::Route                           | MyVpc/PrivateSubnet1/DefaultRoute (MyVpcPrivateSubnet1DefaultRouteA8CDE2FA) 
 43/50 | 11:37:43 AM | CREATE_IN_PROGRESS   | AWS::EC2::Route                           | MyVpc/PrivateSubnet2/DefaultRoute (MyVpcPrivateSubnet2DefaultRoute9CE96294) Resource creation Initiated
 44/50 | 11:37:59 AM | CREATE_COMPLETE      | AWS::EC2::Route                           | MyVpc/PrivateSubnet2/DefaultRoute (MyVpcPrivateSubnet2DefaultRoute9CE96294) 
 45/50 | 11:38:11 AM | CREATE_COMPLETE      | AWS::ElasticLoadBalancingV2::LoadBalancer | Ec2Service/LB (Ec2ServiceLB381329CE) 
 45/50 | 11:38:15 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::Listener     | Ec2Service/LB/PublicListener (Ec2ServiceLBPublicListenerA941070C) 
 45/50 | 11:38:15 AM | CREATE_IN_PROGRESS   | AWS::ElasticLoadBalancingV2::Listener     | Ec2Service/LB/PublicListener (Ec2ServiceLBPublicListenerA941070C) Resource creation Initiated
 46/50 | 11:38:16 AM | CREATE_COMPLETE      | AWS::ElasticLoadBalancingV2::Listener     | Ec2Service/LB/PublicListener (Ec2ServiceLBPublicListenerA941070C) 
 46/50 | 11:38:20 AM | CREATE_IN_PROGRESS   | AWS::ECS::Service                         | Ec2Service/Service/Service (Ec2Service398F0E46) 
 46/50 | 11:38:21 AM | CREATE_IN_PROGRESS   | AWS::ECS::Service                         | Ec2Service/Service/Service (Ec2Service398F0E46) Resource creation Initiated
46/50 Currently in progress: Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0, Ec2Service398F0E46
 47/50 | 11:39:12 AM | CREATE_COMPLETE      | AWS::AutoScaling::AutoScalingGroup        | Ec2Cluster/DefaultAutoScalingGroup/ASG (Ec2ClusterDefaultAutoScalingGroupASGC5A6D4C0) 
 47/50 | 11:39:17 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::LifecycleHook           | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHook5CB1467E) 
 47/50 | 11:39:18 AM | CREATE_IN_PROGRESS   | AWS::AutoScaling::LifecycleHook           | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHook5CB1467E) Resource creation Initiated
 48/50 | 11:39:18 AM | CREATE_COMPLETE      | AWS::AutoScaling::LifecycleHook           | Ec2Cluster/DefaultAutoScalingGroup/LifecycleHookDrainHook (Ec2ClusterDefaultAutoScalingGroupLifecycleHookDrainHook5CB1467E) 
48/50 Currently in progress: Ec2Service398F0E46
 49/50 | 11:40:22 AM | CREATE_COMPLETE      | AWS::ECS::Service                         | Ec2Service/Service/Service (Ec2Service398F0E46) 
 50/50 | 11:40:26 AM | CREATE_COMPLETE      | AWS::CloudFormation::Stack                | Bonjour 

 ✅  Bonjour

Outputs:
Bonjour.Ec2ServiceLoadBalancerDNS6983C9B2 = Bonjo-Ec2Se-1A3MUCXOPEOUH-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com
Bonjour.LoadBalancerDNS = Bonjo-Ec2Se-1A3MUCXOPEOUH-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxx:stack/Bonjour/73780da0-6fa7-11e9-9437-0e72822fc3e0
```

#### 動作確認
OutputされたELBのURLにアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345960/4a032bd0-f0ca-87d5-58a9-9733429c92c5.png)
サンプルアプリが表示されました。

ECS Serviceを確認します。

```sh
aws ecs describe-services --cluster  Bonjour-Ec2ClusterEE43E89D-10ZEEGEWTOSJM --services 
Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC 
```
```json
{
    "services": [
        {
            "serviceArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxx:service/Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC",
            "serviceName": "Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxx:cluster/Bonjour-Ec2ClusterEE43E89D-10ZEEGEWTOSJM",
            "loadBalancers": [
                {
                    "targetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxx:targetgroup/Bonjo-Ec2Se-ZEBMGDX3701N/d7c55f76db539196",
                    "containerName": "web",
                    "containerPort": 80
                }
            ],
            "serviceRegistries": [],
            "status": "ACTIVE",
            "desiredCount": 1,
            "runningCount": 1,
            "pendingCount": 0,
            "launchType": "EC2",
            "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxx:task-definition/BonjourEc2ServiceTaskDef2C3EE7C1:1",
            "deploymentConfiguration": {
                "maximumPercent": 200,
                "minimumHealthyPercent": 50
            },
            "deployments": [
                {
                    "id": "ecs-svc/9223370479744474602",
                    "status": "PRIMARY",
                    "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxx:task-definition/BonjourEc2ServiceTaskDef2C3EE7C1:1",
                    "desiredCount": 1,
                    "pendingCount": 0,
                    "runningCount": 1,
                    "createdAt": 1557110301.205,
                    "updatedAt": 1557110412.881,
                    "launchType": "EC2"
                }
            ],
            "roleArn": "arn:aws:iam::xxxxxxxxxx:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
            "events": [
                {
                    "id": "37a6a1c7-a198-42b9-9af3-b1f6ba01b735",
                    "createdAt": 1557110412.889,
                    "message": "(service Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC) has reached a steady state."
                },
                {
                    "id": "24d2abc5-c8c1-4e82-ac1f-99ae8651b337",
                    "createdAt": 1557110390.039,
                    "message": "(service Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC) registered 1 targets in (target-group arn:aws:elasticloadbalancing:ap-northeast-1:xxxxxxxxxx:targetgroup/Bonjo-Ec2Se-ZEBMGDX3701N/d7c55f76db539196)"
                },
                {
                    "id": "2cd54fa3-8f26-4f7c-9a0e-556920496323",
                    "createdAt": 1557110368.539,
                    "message": "(service Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC) has started 1 tasks: (task 9f502db6-5a7a-433b-858b-18feb80ce01a)."
                },
                {
                    "id": "8fe3d401-4dee-404e-bb30-b6154570177c",
                    "createdAt": 1557110302.67,
                    "message": "(service Bonjour-Ec2Service398F0E46-1D6RQQKKMTFQC) was unable to place a task because no container instance met all of its requirements. Reason: No Container Instances were found in your cluster. For more information, see the Troubleshooting section of the Amazon ECS Developer Guide."
                }
            ],
            "createdAt": 1557110301.205,
            "placementConstraints": [],
            "placementStrategy": [],
            "healthCheckGracePeriodSeconds": 0,
            "schedulingStrategy": "REPLICA",
            "enableECSManagedTags": false,
            "propagateTags": "NONE"
        }
    ],
    "failures": []
}
```

ECS Service、ホストのEC2インスタンスのAutoScalingはスケーリングポリシーは設定されずDesired Capacityを指定して手動スケールする設定となっていました。