Exemplo n.º 1
0
 def wrapper(*args, **kwargs):
     kwargs['services'] = {
         'sysvinit': InitServices(
             {
                 'cfn-hup': InitService(
                     ensureRunning='true',
                     enabled='true',
                     files=[
                         '/etc/cfn/cfn-hup.conf',
                         '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                     ]
                 )
             }
         )
     }
     return(func(*args, **kwargs))
Exemplo n.º 2
0
                     ' --resource ContainerInstances ',
                     ' --region ',
                     Ref('AWS::Region'),
                     '\n',  # NOQA
                     'runas=root\n'
                 ]),
             mode='000400',
             owner='root',
             group='root')
     }, ),
 services=InitServices({
     'cfn-hup':
     InitService(
         ensureRunning='true',
         enabled='true',
         files=[
             '/etc/cfn/cfn-hup.conf',
             '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
         ])
 }),
 commands={
     '01_add_instance_to_cluster': {
         'command':
         Join(
             '',
             [
                 '#!/bin/bash\n',  # NOQA
                 'echo ECS_CLUSTER=',  # NOQA
                 Ref('ECSCluster'),  # NOQA
                 ' >> /etc/ecs/ecs.config'
             ])
Exemplo n.º 3
0
    def add_ec2_instance(self):

        instance_metadata = Metadata(
            Init({
                'config':
                InitConfig(
                    packages={'yum': {
                        'openvpn': []
                    }},
                    files=InitFiles({
                        '/etc/openvpn/server.conf':
                        InitFile(content=Join('\n', [
                            'port 1194',
                            'proto tcp-server',
                            'dev tun1',
                            'ifconfig 172.16.1.2 172.16.1.3',
                            'status server-tcp.log',
                            'verb 3',
                            'secret /etc/openvpn/static.key',
                            'keepalive 10 60',
                            'ping-timer-rem',
                            'persist-tun',
                            'persist-key',
                            'user nobody',
                            'group nobody',
                            'daemon',
                        ]),
                                 mode='000644',
                                 owner='root',
                                 group='root'),
                        '/etc/openvpn/client.ovpn':
                        InitFile(content=Join('\n', [
                            'proto tcp-client',
                            'remote {{public_ip}}',
                            'port 1194',
                            'dev tun',
                            'secret /tmp/secret.key',
                            'ifconfig 10.4.0.2 10.4.0.1',
                        ]),
                                 mode='000644',
                                 owner='root',
                                 group='root'),
                        '/etc/cfn/cfn-hup.conf':
                        InitFile(content=Join('', [
                            '[main]\n',
                            'stack=',
                            Ref('AWS::StackId'),
                            '\n',
                            'region=',
                            Ref('AWS::Region'),
                            '\n',
                        ]),
                                 mode='000400',
                                 owner='root',
                                 group='root'),
                        '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                        InitFile(content=Join('', [
                            '[cfn-auto-reloader-hook]\n',
                            'triggers=post.update\n',
                            'path=Resources.OpenVpn.Metadata.AWS::CloudFormation::Init\n',
                            'action=/opt/aws/bin/cfn-init -v --stack ',
                            Ref('AWS::StackName'),
                            '--resource OpenVpn ',
                            ' --region ',
                            Ref('AWS::Region'),
                            '\n',
                            'runas=root\n',
                        ]))
                    }),
                    services={
                        'sysvinit':
                        InitServices({
                            'openvpn':
                            InitService(enabled=True,
                                        ensureRunning=True,
                                        files=['/etc/openvpn/server.conf']),
                            'cfn-hup':
                            InitService(
                                enabled=True,
                                ensureRunning=True,
                                files=[
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ])
                        })
                    })
            }))

        self.ec2_instance = self.template.add_resource(
            ec2.Instance(
                "OpenVpn",
                ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"),
                InstanceType="t2.micro",
                KeyName=self.sceptre_user_data["keyname"],
                SecurityGroupIds=[Ref(self.securityGroup)],
                IamInstanceProfile=Ref(self.cfninstanceprofile),
                SubnetId=ImportValue('deploy-dev-vpc-PublicSubnet'),
                Metadata=instance_metadata,
                UserData=Base64(
                    Join('', [
                        '#!/bin/bash -xe\n',
                        'yum install easy-rsa -y --enablerepo=epel\n',
                        'yum update -y aws-cfn-bootstrap\n',
                        '/opt/aws/bin/cfn-init -v --stack ',
                        Ref('AWS::StackName'),
                        ' --resource OpenVpn --region ',
                        Ref('AWS::Region'),
                        '\n',
                        '/opt/aws/bin/cfn-signal -e $? --stack ',
                        Ref('AWS::StackName'),
                        ' --resource OpenVpn --region ',
                        Ref('AWS::Region'),
                        '\n',
                        'cd /etc/openvpn\n',
                        'openvpn --genkey --secret static.key\n',
                        'aws s3 cp static.key s3://',
                        ImportValue('deploy-dev-s3bucket-s3bucketname'),
                        '/\n',
                        'sudo modprobe iptable_nat',
                        '\n',
                        'echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward',
                        '\n',
                        'sudo iptables -t nat -A POSTROUTING -s 10.4.0.1/2 -o eth0 -j MASQUERADE',
                        '\n',
                        'external_ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4`',
                        '\n',
                        'sed -i "s|{{public_ip}}|$external_ip|g" /etc/openvpn/client.ovpn',
                        '\n',
                        'aws s3 cp client.ovpn s3://',
                        ImportValue('deploy-dev-s3bucket-s3bucketname'),
                        '\n',
                    ])),
                CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                    Timeout='PT15M')),
                Tags=Tags(Name="vpn-server"),
            ))
                                  'triggers=post.update\n',
                                  'path=Resources.WebServerInstance.\
Metadata.AWS::CloudFormation::Init\n',
                                  'action=/opt/aws/bin/cfn-init -v ',
                                  '         --stack ',
                                  ref_stack_name,
                                  '         --resource WebServerInstance ',
                                  '         --region ',
                                  ref_region,
                                  '\n',
                                  'runas=root\n',
                                  ]))}),
            services={
                'sysvinit': InitServices({
                    'httpd': InitService(
                        enabled=True,
                                         ensureRunning=True),
                    'cfn-hup': InitService(
                        enabled=True,
                        ensureRunning=True,
                        files=[
                            '/etc/cfn/cfn-hup.conf',
                            '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                        ])})})}))

instance = t.add_resource(
    Instance(
        'WebServerInstance',
        Metadata=instance_metadata,
        ImageId=FindInMap(
            'AWSRegionArch2AMI',
Exemplo n.º 5
0
def build_template(keyPair, instanceType):
    ''' Builds the CloudFormation template which will create EC2 and supporting resources. '''
    print
    print '################ 2. Template Build Phase ################'
    print 'Starting CloudFormation template build.'

    ### Template Info ###
    mini_template = Template()

    # Define template version and description
    mini_template.add_version('2010-09-09')
    mini_template.add_description(
        'Provisions VPC, IGW, Route Table, Subnet, and EC2 instance in AWS to support a static website.'
    )

    ### Parameters ###
    instance_type = mini_template.add_parameter(
        Parameter(
            'InstanceType',
            Type='String',
            Description='EC2 instance type',
            Default=instanceType,
            AllowedValues=[
                't1.micro', 't2.micro', 't2.small', 't2.medium', 'm1.small',
                'm1.medium', 'm1.large', 'm1.xlarge', 'm2.xlarge',
                'm2.2xlarge', 'm2.4xlarge', 'm3.medium', 'm3.large',
                'm3.xlarge', 'm3.2xlarge', 'm4.large', 'm4.xlarge',
                'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge', 'c1.medium',
                'c1.xlarge', 'c3.large', 'c3.xlarge', 'c3.2xlarge',
                'c3.4xlarge', 'c3.8xlarge', 'c4.large', 'c4.xlarge',
                'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', 'g2.2xlarge',
                'r3.large', 'r3.xlarge', 'r3.2xlarge', 'r3.4xlarge',
                'r3.8xlarge', 'i2.xlarge', 'i2.2xlarge', 'i2.4xlarge',
                'i2.8xlarge', 'd2.xlarge', 'd2.2xlarge', 'd2.4xlarge',
                'd2.8xlarge', 'hi1.4xlarge', 'hs1.8xlarge', 'cr1.8xlarge',
                'cc2.8xlarge', 'cg1.4xlarge'
            ],
            ConstraintDescription='must be a valid EC2 instance type.',
        ))

    ### Mappings ###

    # AMI Mapping for Amazon Linux AMI as of 03-Jan-2017
    mini_template.add_mapping(
        'AWSRegionArch2AMI', {
            'us-east-1': {
                'HVM64': 'ami-9be6f38c'
            },
            'us-east-2': {
                'HVM64': 'ami-38cd975d'
            },
            'us-west-1': {
                'HVM64': 'ami-b73d6cd7'
            },
            'us-west-2': {
                'HVM64': 'ami-1e299d7e'
            },
            'ca-central-1': {
                'HVM64': 'ami-eb20928f'
            },
            'eu-west-1': {
                'HVM64': 'ami-c51e3eb6'
            },
            'eu-west-2': {
                'HVM64': 'ami-bfe0eadb'
            },
            'eu-central-1': {
                'HVM64': 'ami-211ada4e'
            },
            'ap-southeast-1': {
                'HVM64': 'ami-4dd6782e'
            },
            'ap-southeast-2': {
                'HVM64': 'ami-28cff44b'
            },
            'ap-northeast-1': {
                'HVM64': 'ami-9f0c67f8'
            },
            'ap-northeast-2': {
                'HVM64': 'ami-94bb6dfa'
            },
            'ap-south-1': {
                'HVM64': 'ami-9fc7b0f0'
            },
            'sa-east-1': {
                'HVM64': 'ami-bb40d8d7'
            }
        })

    ### Resources ###

    # VPC
    vpc = mini_template.add_resource(
        VPC('VPC',
            CidrBlock='172.16.0.0/16',
            EnableDnsSupport='True',
            EnableDnsHostnames='True',
            Tags=Tags(Name=stack_name + '-vpc', Project=stack_name)))

    # Internet Gateway
    igw = mini_template.add_resource(
        InternetGateway('InternetGateway',
                        Tags=Tags(Name=stack_name + '-igw',
                                  Project=stack_name)))

    # Attach IGW to VPC
    attach_gateway = mini_template.add_resource(
        VPCGatewayAttachment('AttachGateway',
                             VpcId=Ref(vpc),
                             InternetGatewayId=Ref(igw)))

    # Route Table
    route_table = mini_template.add_resource(
        RouteTable('RouteTable',
                   VpcId=Ref(vpc),
                   Tags=Tags(Name=stack_name + '-routetable',
                             Project=stack_name)))

    # Route 0.0.0.0 -> IGW
    route01 = mini_template.add_resource(
        Route('Route',
              DependsOn='AttachGateway',
              GatewayId=Ref(igw),
              DestinationCidrBlock='0.0.0.0/0',
              RouteTableId=Ref(route_table)))

    # Subnet
    subnet = mini_template.add_resource(
        Subnet('Subnet',
               CidrBlock='172.16.10.0/24',
               VpcId=Ref(vpc),
               MapPublicIpOnLaunch='True',
               Tags=Tags(Name=stack_name + '-subnet', Project=stack_name)))

    # Subnet -> Route Table
    subnet_route_associate = mini_template.add_resource(
        SubnetRouteTableAssociation('SubnetRouteTableAssociation',
                                    SubnetId=Ref(subnet),
                                    RouteTableId=Ref(route_table)))

    # Security Group allowing access via SSH and HTTP
    web_security_group = mini_template.add_resource(
        SecurityGroup('WebSecurityGroup',
                      GroupDescription=
                      'Enable access to the web server on ports 80 and 22.',
                      VpcId=Ref(vpc),
                      Tags=Tags(Name=stack_name + '-securitygroup',
                                Project=stack_name),
                      SecurityGroupIngress=[
                          SecurityGroupRule(IpProtocol='tcp',
                                            FromPort='22',
                                            ToPort='22',
                                            CidrIp='0.0.0.0/0'),
                          SecurityGroupRule(IpProtocol='tcp',
                                            FromPort='80',
                                            ToPort='80',
                                            CidrIp='0.0.0.0/0')
                      ]))

    # Metadata to install Apache
    ec2_metadata = Metadata(
        Init({
            'config':
            InitConfig(
                packages={'yum': {
                    'httpd': []
                }},
                files=InitFiles({
                    '/var/www/html/index.html':
                    InitFile(
                        content=
                        '<html><body><h2>Automation for the People!</h2></body></html>',
                        mode='000644',
                        owner='root',
                        group='root')
                }),
                services={
                    'sysvinit':
                    InitServices({
                        'httpd':
                        InitService(enabled=True, ensureRunning=True)
                    })
                })
        }))

    # EC2 Instance
    ec2 = mini_template.add_resource(
        Instance('Ec2Instance',
                 ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'),
                                   'HVM64'),
                 Metadata=ec2_metadata,
                 InstanceType=Ref(instance_type),
                 KeyName=keyPair,
                 SecurityGroupIds=[
                     Ref(web_security_group),
                 ],
                 SubnetId=Ref(subnet),
                 Tags=Tags(Name=stack_name + '-ec2', Project=stack_name),
                 CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(
                     Timeout='PT15M')),
                 UserData=Base64(
                     Join('', [
                         '#!/bin/bash -x\n',
                         'yum update -y\n',
                         'yum update -y aws-cfn-bootstrap\n',
                         '/opt/aws/bin/cfn-init -v ',
                         '         --stack ',
                         Ref('AWS::StackName'),
                         '         --resource Ec2Instance ',
                         '         --region ',
                         Ref('AWS::Region'),
                         '\n',
                         '/opt/aws/bin/cfn-signal -e $? ',
                         '         --stack ',
                         Ref('AWS::StackName'),
                         '         --resource Ec2Instance ',
                         '         --region ',
                         Ref('AWS::Region'),
                         '\n',
                     ]))))

    ### Outputs ###

    # Output the Public DNS address for the EC2 instance
    mini_template.add_output(
        Output('URL',
               Description='HTTP Server URL',
               Value=Join('',
                          ['http://',
                           GetAtt('Ec2Instance', 'PublicDnsName')])))

    print 'CloudFormation template build is completed.'
    return mini_template
Exemplo n.º 6
0
                                    "         --stack ",
                                    ref_stack_name,
                                    "         --resource WebServerInstance ",
                                    "         --region ",
                                    ref_region,
                                    "\n",
                                    "runas=root\n",
                                ],
                            )
                        ),
                    }
                ),
                services={
                    "sysvinit": InitServices(
                        {
                            "httpd": InitService(enabled=True, ensureRunning=True),
                            "cfn-hup": InitService(
                                enabled=True,
                                ensureRunning=True,
                                files=[
                                    "/etc/cfn/cfn-hup.conf",
                                    "/etc/cfn/hooks.d/cfn-auto-reloader.conf",
                                ],
                            ),
                        }
                    )
                },
            )
        }
    )
)
Exemplo n.º 7
0
path=Resources.NetKANCompute.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r NetKANCompute --region ${AWS::Region}
runas=root
"""))
docker = InitFile(content="""
{
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "20m",
        "max-file": "3"
    }
}
""")
cfn_service = InitService(enabled=True,
                          ensureRunning=True,
                          files=[
                              '/etc/cfn/cfn-hup.conf',
                              '/etc/cfn/hooks.d/cfn-auto-reloader.conf',
                          ])
docker_service = InitService(enabled=True,
                             ensureRunning=True,
                             files=['/etc/docker/daemon.json'])
netkan_instance = Instance(
    'NetKANCompute',
    # ECS Optimised us-west-2
    ImageId='ami-064803387adcb64b3',
    InstanceType='t3.small',
    IamInstanceProfile=Ref(netkan_profile),
    KeyName='techman83_alucard',
    SecurityGroups=['ckan-bot'],
    UserData=Base64(netkan_userdata),
    # t3 instances are unlimited by default
Exemplo n.º 8
0
                     "\n",  # NOQA
                     "runas=root\n",
                 ],
             ),
             mode="000400",
             owner="root",
             group="root",
         ),
     },
 ),
 services=InitServices(
     {
         "cfn-hup": InitService(
             ensureRunning="true",
             enabled="true",
             files=[
                 "/etc/cfn/cfn-hup.conf",
                 "/etc/cfn/hooks.d/cfn-auto-reloader.conf",
             ],
         )
     }
 ),
 commands={
     "01_add_instance_to_cluster": {
         "command": Join(
             "",
             [
                 "#!/bin/bash\n",  # NOQA
                 "echo ECS_CLUSTER=",  # NOQA
                 Ref("ECSCluster"),  # NOQA
                 " >> /etc/ecs/ecs.config",
             ],
Exemplo n.º 9
0
def main():
    """Generates the CloudFormation template"""
    template = Template()
    template.add_version('2010-09-09')
    template.add_description(
        'This template deploys an ECS cluster to the ' +
        'provided VPC and subnets using an Auto Scaling Group')

    # Parameters
    # EnvironmentName
    env_name_param = template.add_parameter(
        Parameter(
            'EnvironmentName',
            Type='String',
            Description=
            'An environment name that will be prefixed to resource names',
        ))

    # InstanceType
    instance_type_param = template.add_parameter(
        Parameter(
            'InstanceType',
            Type='String',
            Default='t2.nano',
            Description=
            'Which instance type should we use to build the ECS cluster?',
            AllowedValues=[
                't2.nano',
                't2.micro',
                't2.small',
                't2.medium',
                't2.large',
                't2.xlarge',
                't2.2xlarge',
            ],
        ))

    # ClusterSize
    cluster_size_param = template.add_parameter(
        Parameter(
            'ClusterSize',
            Type='Number',
            Description='How many ECS hosts do you want to initially deploy?',
            Default='1',
        ))

    # VPC
    template.add_parameter(
        Parameter(
            'VPC',
            Type='AWS::EC2::VPC::Id',
            Description=
            'Choose which VPC this ECS cluster should be deployed to',
        ))

    # Subnets
    subnets_param = template.add_parameter(
        Parameter(
            'Subnets',
            Type='List<AWS::EC2::Subnet::Id>',
            Description=
            'Choose which subnets this ECS cluster should be deployed to',
        ))

    # SecurityGroup
    sg_param = template.add_parameter(
        Parameter(
            'SecurityGroup',
            Type='AWS::EC2::SecurityGroup::Id',
            Description=
            'Select the Security Group to use for the ECS cluster hosts',
        ))

    # Mappings
    # AWSRegionToAMI
    template.add_mapping(
        'AWSRegionToAMI',
        {
            'us-east-1': {
                'AMI': 'ami-a58760b3'
            },
            'us-east-2': {
                'AMI': 'ami-a6e4bec3'
            },
            'us-west-1': {
                'AMI': 'ami-74cb9b14'
            },
            'us-west-2': {
                'AMI': 'ami-5b6dde3b'
            },
            'eu-west-1': {
                'AMI': 'ami-e3fbd290'
            },
            'eu-west-2': {
                'AMI': 'ami-77f6fc13'
            },
            'eu-central-1': {
                'AMI': 'ami-38dc1157'
            },
            'ap-northeast-1': {
                'AMI': 'ami-30bdce57'
            },
            'ap-southeast-1': {
                'AMI': 'ami-9f75ddfc'
            },
            'ap-southeast-2': {
                'AMI': 'ami-cf393cac'
            },
            'ca-central-1': {
                'AMI': 'ami-1b01b37f'
            },
        },
    )

    # Resources
    ecs_role = template.add_resource(
        Role(
            'ECSRole',
            Path='/',
            RoleName=Sub('${EnvironmentName}-ECSRole-${AWS::Region}'),
            AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[
                awacs.aws.Statement(
                    Effect=awacs.aws.Allow,
                    Action=[awacs.aws.Action('sts', 'AssumeRole')],
                    Principal=awacs.aws.Principal('Service',
                                                  ['ec2.amazonaws.com']),
                ),
            ]),
            Policies=[
                Policy(
                    PolicyName='ecs-service',
                    PolicyDocument=awacs.aws.Policy(Statement=[
                        awacs.aws.Statement(
                            Effect=awacs.aws.Allow,
                            Action=[
                                awacs.aws.Action('ecs', 'CreateCluster'),
                                awacs.aws.Action(
                                    'ecs', 'DeregisterContainerInstance'),
                                awacs.aws.Action('ecs',
                                                 'DiscoverPollEndpoint'),
                                awacs.aws.Action('ecs', 'Poll'),
                                awacs.aws.Action('ecs',
                                                 'RegisterContainerInstance'),
                                awacs.aws.Action('ecs',
                                                 'StartTelemetrySession'),
                                awacs.aws.Action('ecs', 'Submit*'),
                                awacs.aws.Action('logs', 'CreateLogStream'),
                                awacs.aws.Action(
                                    'ecr', 'BatchCheckLayerAvailability'),
                                awacs.aws.Action('ecr', 'BatchGetImage'),
                                awacs.aws.Action('ecr',
                                                 'GetDownloadUrlForLayer'),
                                awacs.aws.Action('ecr',
                                                 'GetAuthorizationToken'),
                            ],
                            Resource=['*'],
                        ),
                    ], ),
                ),
            ],
        ))

    ecs_instance_profile = template.add_resource(
        InstanceProfile(
            'ECSInstanceProfile',
            Path='/',
            Roles=[Ref(ecs_role)],
        ))

    # ECSCluster
    ecs_cluster = template.add_resource(
        Cluster(
            'ECSCluster',
            ClusterName=Ref(env_name_param),
        ))

    instance_metadata = Metadata(
        Init({
            'config':
            InitConfig(
                commands={
                    '01_add_instance_to_cluster': {
                        'command':
                        Join('', [
                            '#!/bin/bash\n', 'echo ECS_CLUSTER=',
                            Ref(ecs_cluster), ' >> /etc/ecs/ecs.config'
                        ])
                    },
                },
                files=InitFiles({
                    '/etc/cfn/cfn-hup.conf':
                    InitFile(
                        mode='000400',
                        owner='root',
                        group='root',
                        content=Join('', [
                            '[main]\n', 'stack=',
                            Ref('AWS::StackId'), '\n', 'region=',
                            Ref('AWS::Region'), '\n'
                        ]),
                    ),
                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                    InitFile(
                        mode='000400',
                        owner='root',
                        group='root',
                        content=Join('', [
                            '[cfn-auto-reloader-hook]\n',
                            'triggers=post.update\n',
                            'path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init\n'
                            'action=/opt/aws/bin/cfn-init -v --region ',
                            Ref('AWS::Region'), ' --stack ',
                            Ref('AWS::StackId'),
                            ' --resource ECSLaunchConfiguration\n'
                        ]),
                    )
                }),
                services=InitServices({
                    'cfn-hup':
                    InitService(enabled='true',
                                ensureRunning='true',
                                files=[
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ])
                }),
            )
        }))

    ecs_launch_config = template.add_resource(
        LaunchConfiguration(
            'ECSLaunchConfiguration',
            ImageId=FindInMap('AWSRegionToAMI', Ref('AWS::Region'), 'AMI'),
            InstanceType=Ref(instance_type_param),
            SecurityGroups=[Ref(sg_param)],
            IamInstanceProfile=Ref(ecs_instance_profile),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'yum install -y aws-cfn-bootstrap\n',
                    '/opt/aws/bin/cfn-init -v --region ',
                    Ref('AWS::Region'),
                    ' --stack ',
                    Ref('AWS::StackName'),
                    ' --resource ECSLaunchConfiguration\n',
                    '/opt/aws/bin/cfn-signal -e $? --region ',
                    Ref('AWS::Region'),
                    ' --stack ',
                    Ref('AWS::StackName'),
                    ' --resource ECSAutoScalingGroup\n',
                ])),
            Metadata=instance_metadata,
        ))

    # ECSAutoScalingGroup:
    template.add_resource(
        AutoScalingGroup(
            'ECSAutoScalingGroup',
            VPCZoneIdentifier=Ref(subnets_param),
            LaunchConfigurationName=Ref(ecs_launch_config),
            MinSize=Ref(cluster_size_param),
            MaxSize=Ref(cluster_size_param),
            DesiredCapacity=Ref(cluster_size_param),
            Tags=ASTags(Name=(Sub('${EnvironmentName} ECS host'), True)),
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(Timeout='PT15M'), ),
            UpdatePolicy=UpdatePolicy(
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    MinInstancesInService='1',
                    MaxBatchSize='1',
                    PauseTime='PT15M',
                    WaitOnResourceSignals=True,
                )),
        ))

    # Output
    template.add_output(
        Output(
            'Cluster',
            Description='A reference to the ECS cluster',
            Value=Ref(ecs_cluster),
        ))
    print(template.to_json())