def wrapper(*args, **kwargs): kwargs['files'] = InitFiles( { '/etc/cfn/cfn-hup.conf': InitFile( content=Join('', [ '[main]\n', 'stack=', Ref('AWS::StackId'), '\n', 'region=', Ref('AWS::Region'), '\n' ] ), mode='00400', 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.ContainerInstances', '.Metadata.AWS::CloudFormation::Init\n', 'action=/opt/aws/bin/cfn-init -v ', '--stack ', Ref('AWS::StackName'), ' ', '--resource ContainerInstances ', '--region ', Ref('AWS::Region'), '\n', 'runas=root\n' ] ), mode='00400', owner='root', group='root' ) } ) return(func(*args, **kwargs))
InstanceProfileName='TweeterUploaderInstanceProfile')) # Define Instance Metadata instance_metadata = Metadata( Init({ 'config': InitConfig( commands={'update_yum_packages': { 'command': 'yum update -y' }}, files=InitFiles({ # setup .bashrc ec2-user '/home/ec2-user/.bashrc': InitFile(content=Join( '', ['export PATH="/home/ec2-user/miniconda/bin:$PATH"\n']), owner='ec2-user', mode='000400', group='ec2-user'), # setup .bashrc root '/root/.bashrc': InitFile(content=Join('', [ 'export PATH="/home/ec2-user/miniconda/bin:$PATH"\n' f'export STREAM_NAME="{STREAM_NAME}"\n', f'export PRODUCER_NAME="{SERVER_NAME}"\n', f'export TWITTER_KEYWORDS="{TWITTER_KEYWORDS}"\n', 'export ENV="production"\n' ]), owner='root', mode='000400', group='root'), # configure cfn-hup
ToPort='80', CidrIp='0.0.0.0/0')], VpcId=Ref(VPC), )) instance_metadata = Metadata( Init({ 'config': InitConfig( packages={'yum': {'httpd': []}}, files=InitFiles({ '/var/www/html/index.html': InitFile(content=Join('\n', [ '<img \ src="https://s3.amazonaws.com/cloudformation-examples/\ cloudformation_graphic.png" alt="AWS CloudFormation Logo"/>', '<h1>\ Congratulations, you have successfully launched the AWS CloudFormation sample.\ </h1>']), mode='000644', owner='root', group='root'), '/etc/cfn/cfn-hup.conf': InitFile(content=Join('', ['[main]\n', 'stack=', ref_stack_id, '\n', 'region=', ref_region, '\n', ]), mode='000400',
def main(): '''Function: Generates the Cloudformation template''' template = Template() keyname_param = template.add_parameter( Parameter( 'KeyName', Description='Name of an existing EC2 KeyPair for SSH access', ConstraintDescription='Must be the name of an existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', ) ) password_param = template.add_parameter( Parameter( 'PassWord', Type='String', NoEcho=True, MinLength=8, MaxLength=64, Description='Password for the admin account', ConstraintDescription='A complex password at least eight chars long with alphanumeric characters, dashes and underscores.', AllowedPattern="[-_a-zA-Z0-9]*", ) ) template.add_mapping('RegionMap', {'ap-south-1': {'ami': 'ami-ee8ea481'}, 'eu-west-3': {'ami': 'ami-daf040a7'}, 'eu-west-2': {'ami': 'ami-ddb950ba'}, 'eu-west-1': {'ami': 'ami-d2414e38'}, 'ap-northeast-2': {'ami': 'ami-65d86d0b'}, 'ap-northeast-1': {'ami': 'ami-e875a197'}, 'sa-east-1': {'ami': 'ami-ccd48ea0'}, 'ca-central-1': {'ami': 'ami-c3e567a7'}, 'ap-southeast-1': {'ami': 'ami-31e7e44d'}, 'ap-southeast-2': {'ami': 'ami-23c51c41'}, 'eu-central-1': {'ami': 'ami-3c635cd7'}, 'us-east-1': {'ami': 'ami-5cc39523'}, 'us-east-2': {'ami': 'ami-67142d02'}, 'us-west-1': {'ami': 'ami-d7b355b4'}, 'us-west-2': {'ami': 'ami-39c28c41'}}) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'SecurityGroup', GroupDescription='SSH, HTTP/HTTPS open for 0.0.0.0/0', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0'), ], ) ) ec2_role = template.add_resource( Role('EC2Role', AssumeRolePolicyDocument={ "Version" : "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, ) ) ec2_policy = template.add_resource( ManagedPolicy( 'EC2Policy', PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Action": "ec2:*", "Resource": "*", "Effect": "Allow" } ] }, Roles=[Ref(ec2_role)] ) ) ec2_profile = template.add_resource( InstanceProfile("EC2InstanceProfile", Roles=[Ref(ec2_role)]) ) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig( files=InitFiles({ "/etc/nginx/conf.d/jenkins.conf": InitFile( content='server { listen 80 default_server; listen [::]:80 default_server; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }', mode="000644", owner="root", group="root" ) }), ) }), ), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal(Timeout='PT15M') ), ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'), InstanceType='t2.micro', IamInstanceProfile=Ref(ec2_profile), KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group)], UserData=Base64( Join( '', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n' 'unset UCF_FORCE_CONFFOLD\n', 'export UCF_FORCE_CONFFNEW=YES\n', 'ucf --purge /boot/grub/menu.lst\n', 'export DEBIAN_FRONTEND=noninteractive\n', 'echo "deb http://pkg.jenkins-ci.org/debian binary/" > /etc/apt/sources.list.d/jenkins.list\n', 'wget -q -O jenkins-ci.org.key http://pkg.jenkins-ci.org/debian-stable/jenkins-ci.org.key\n' 'apt-key add jenkins-ci.org.key\n', 'apt-get update\n', 'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n', 'apt-get install -y python-pip\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', 'apt-get install -y nginx\n', 'apt-get install -y openjdk-8-jdk\n', 'apt-get install -y jenkins\n', '# Wait for Jenkins to Set Up\n' "until [ $(curl -o /dev/null --silent --head --write-out '%{http_code}\n' http://localhost:8080) -eq 403 ]; do sleep 1; done\n", 'sleep 10\n', '# Change the password for the admin account\n', "echo 'jenkins.model.Jenkins.instance.securityRealm.createAccount(\"admin\", \"",Ref(password_param),"\")' | java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s \"http://localhost:8080/\" -auth \"admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword)\" groovy =\n", '/usr/local/bin/cfn-init --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', 'unlink /etc/nginx/sites-enabled/default\n', 'systemctl reload nginx\n', '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', ] ) ) ) ) template.add_output([ Output( 'PublicDnsName', Description='PublicDnsName', Value=Join('',['http://', GetAtt(ec2_instance, 'PublicDnsName'),]) ), ]) print(template.to_yaml())
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
instance_metadata = Metadata( Init( { "config": InitConfig( packages={"yum": {"httpd": []}}, files=InitFiles( { "/var/www/html/index.html": InitFile( content=Join( "\n", [ '<img \ src="https://s3.amazonaws.com/cloudformation-examples/\ cloudformation_graphic.png" alt="AWS CloudFormation Logo"/>', "<h1>\ Congratulations, you have successfully launched the AWS CloudFormation sample.\ </h1>", ], ), mode="000644", owner="root", group="root", ), "/etc/cfn/cfn-hup.conf": InitFile( content=Join( "", [ "[main]\n", "stack=", ref_stack_id, "\n",
def main(): '''Function: Generates the Cloudformation template''' template = Template() template.add_description("A target server for CI/CD tests.") keyname_param = template.add_parameter( Parameter( 'KeyName', Description='An existing EC2 KeyPair.', ConstraintDescription='An existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', )) template.add_mapping( 'RegionMap', { 'ap-south-1': { 'ami': 'ami-0dba8796fe499ae48' }, 'eu-west-3': { 'ami': 'ami-07b2287c6776361c8' }, 'eu-north-1': { 'ami': 'ami-34c14f4a' }, 'eu-west-2': { 'ami': 'ami-0573b1dbbd809d6c3' }, 'eu-west-1': { 'ami': 'ami-001b0e20a92d8db1e' }, 'ap-northeast-2': { 'ami': 'ami-0dc961dd0c2c83bdd' }, 'ap-northeast-1': { 'ami': 'ami-0f2c38ac2e37197be' }, 'sa-east-1': { 'ami': 'ami-04ab6be036f8635bd' }, 'ca-central-1': { 'ami': 'ami-0de195e1958cc0d52' }, 'ap-southeast-1': { 'ami': 'ami-08540b8d2f7fa85a5' }, 'ap-southeast-2': { 'ami': 'ami-0bbcf853aaf6ca4a6' }, 'eu-central-1': { 'ami': 'ami-0332a5c40cf835528' }, 'us-east-1': { 'ami': 'ami-0edd3706ab2e952c4' }, 'us-east-2': { 'ami': 'ami-050553a7784d00d21' }, 'us-west-1': { 'ami': 'ami-065ebd3e6b63c75d5' }, 'us-west-2': { 'ami': 'ami-00f13b45242aff065' } }) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'EC2SecurityGroup', Tags=[ { 'Key': 'Name', 'Value': Ref('AWS::StackName') }, ], GroupDescription='EC2 Security Group', SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0', Description='SSH'), ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0', Description='HTTP'), ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0', Description='HTTPS'), ], )) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig(files=InitFiles({ "/tmp/instance.txt": InitFile(content=Ref('AWS::StackName'), mode="000644", owner="root", group="root") }), ) }), ), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=[ { 'Key': 'Name', 'Value': Ref('AWS::StackName') }, ], ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'), InstanceType='t2.micro', KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group)], UserData=Base64( Join('', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n', 'unset UCF_FORCE_CONFFOLD\n', 'export UCF_FORCE_CONFFNEW=YES\n', 'ucf --purge /boot/grub/menu.lst\n', 'export DEBIAN_FRONTEND=noninteractive\n', 'apt-get update\n', 'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n', 'apt-get install -y nginx supervisor build-essential libssl-dev libffi-dev python-pip python3-pip python3-dev python3-setuptools python3-venv\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', '# Signal Cloudformation when set up is complete\n', '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', ])))) template.add_output([ Output( 'InstanceDnsName', Description='PublicDnsName', Value=GetAtt(ec2_instance, 'PublicDnsName'), ), ]) print(template.to_yaml())
"ContainerInstances", Metadata=Metadata( Init( { "config": InitConfig( files=InitFiles( { "/etc/cfn/cfn-hup.conf": InitFile( content=Join( "", [ "[main]\n", "stack=", Ref("AWS::StackId"), # NOQA "\n", "region=", Ref("AWS::Region"), "\n", ], ), # NOQA 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.ContainerInstances.Metadata.AWS::CloudFormation::Init\n", # NOQA
def main(): '''Function: Generates the Cloudformation template''' template = Template() template.add_description("Dev Stack") keyname_param = template.add_parameter( Parameter( 'KeyName', Description='An existing EC2 KeyPair.', ConstraintDescription='An existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', )) db_pass_param = template.add_parameter( Parameter( 'DBPass', NoEcho=True, Type='String', Description='The database admin account password', ConstraintDescription='Must contain only alphanumeric characters', AllowedPattern="[-_a-zA-Z0-9]*", )) db_name_param = template.add_parameter( Parameter( 'DBName', Default='miramax', Type='String', Description='The database name', ConstraintDescription= 'Must begin with a letter and contain only alphanumeric characters', AllowedPattern="[-_a-zA-Z0-9]*", )) db_user_param = template.add_parameter( Parameter( 'DBUser', Default='miramax', Type='String', Description='Username for MySQL database access', ConstraintDescription= 'Must begin with a letter and contain only alphanumeric characters', AllowedPattern="[-_a-zA-Z0-9]*", )) template.add_mapping( 'RegionMap', { 'ap-south-1': { 'ami': 'ami-ee8ea481' }, 'eu-west-3': { 'ami': 'ami-daf040a7' }, 'eu-west-2': { 'ami': 'ami-ddb950ba' }, 'eu-west-1': { 'ami': 'ami-d2414e38' }, 'ap-northeast-2': { 'ami': 'ami-65d86d0b' }, 'ap-northeast-1': { 'ami': 'ami-e875a197' }, 'sa-east-1': { 'ami': 'ami-ccd48ea0' }, 'ca-central-1': { 'ami': 'ami-c3e567a7' }, 'ap-southeast-1': { 'ami': 'ami-31e7e44d' }, 'ap-southeast-2': { 'ami': 'ami-23c51c41' }, 'eu-central-1': { 'ami': 'ami-3c635cd7' }, 'us-east-1': { 'ami': 'ami-5cc39523' }, 'us-east-2': { 'ami': 'ami-67142d02' }, 'us-west-1': { 'ami': 'ami-d7b355b4' }, 'us-west-2': { 'ami': 'ami-39c28c41' } }) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'EC2SecurityGroup', Tags=[ { 'Key': 'Name', 'Value': Ref('AWS::StackName') }, ], GroupDescription='EC2 Security Group', SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0', Description='SSH'), ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0', Description='HTTP'), ec2.SecurityGroupRule(IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0', Description='HTTPS'), ], )) db_security_group = template.add_resource( ec2.SecurityGroup('DBSecurityGroup', Tags=[ { 'Key': 'Name', 'Value': Ref('AWS::StackName') }, ], GroupDescription='DB Security Group', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='3306', ToPort='3306', SourceSecurityGroupId=GetAtt( ec2_security_group, "GroupId"), Description='MySQL'), ])) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig(files=InitFiles({ "/tmp/instance.txt": InitFile(content=Ref('AWS::StackName'), mode="000644", owner="root", group="root") }), ) }), ), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=[ { 'Key': 'Name', 'Value': Ref('AWS::StackName') }, ], ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'), InstanceType='t2.micro', KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group), Ref(db_security_group)], DependsOn='Database', UserData=Base64( Join('', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n', 'unset UCF_FORCE_CONFFOLD\n', 'export UCF_FORCE_CONFFNEW=YES\n', 'ucf --purge /boot/grub/menu.lst\n', 'export DEBIAN_FRONTEND=noninteractive\n', 'apt-get update\n', 'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n', 'apt-get install -y python-pip apache2 libapache2-mod-wsgi\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', '# Signal Cloudformation when set up is complete\n', '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', ])))) ip_association = template.add_resource( ec2.EIPAssociation('IPAssociation', InstanceId=Ref(ec2_instance), AllocationId='eipalloc-aa755d96')) db_instance = template.add_resource( DBInstance( 'Database', DBName=Ref(db_name_param), AllocatedStorage=20, DBInstanceClass='db.t2.micro', Engine='MySQL', EngineVersion='5.7.21', MasterUsername=Ref(db_user_param), MasterUserPassword=Ref(db_pass_param), VPCSecurityGroups=[GetAtt(db_security_group, "GroupId")], )) template.add_output([ Output( 'InstanceDnsName', Description='PublicDnsName', Value=GetAtt(ec2_instance, 'PublicDnsName'), ), Output( 'DatabaseDnsName', Description='DBEndpoint', Value=GetAtt(db_instance, 'Endpoint.Address'), ), ]) print(template.to_yaml())
'download_miniconda': { 'command': 'su - ec2-user -c "wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /home/ec2-user/miniconda.sh"', }, 'install_miniconda': { 'command': 'su - ec2-user -c "bash /home/ec2-user/miniconda.sh -b -p /home/ec2-user/miniconda"', }, 'remove_installer': { 'command': 'rm -rf /home/ec2-user/miniconda.sh', } }, files=InitFiles({ # setup .bashrc '/home/ec2-user/.bashrc': InitFile( content=Join('', [ 'export PATH="/home/ec2-user/miniconda/bin:$PATH"\n' ]), owner='ec2-user', mode='000400', group='ec2-user'), # configure cfn-hup '/etc/cfn/cfn-hup.conf': InitFile( content=Join('', ['[main]\n', 'stack=', Ref('AWS::StackId'), '\n', 'region=', Ref('AWS::Region'), '\n', 'interval=2', '\n', ]), mode='000400',
'su - ec2-user -c "wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /home/ec2-user/miniconda.sh"', }, 'install_miniconda': { 'command': 'su - ec2-user -c "bash /home/ec2-user/miniconda.sh -b -p /home/ec2-user/miniconda"', }, 'remove_installer': { 'command': 'rm -rf /home/ec2-user/miniconda.sh', } }, files=InitFiles({ # setup .bashrc '/home/ec2-user/.ssh/authorized_keys': InitFile(content=Join('', [ 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjKxODWLSrmQAemYnpvYchmy7bwWvIKNWpHtfRiD7UKqnUV0euoFWIr9j+OwiNyMp/iopZQh7A8c+B4TYI8pd///J7ZWPSipndJkWc4HrnU37X66mKInGYIaPZAfek69eeUkl5cekqkEd6l6WsBUlrjPvMYtyGdDtd42M+aNQoy1TWq2C/6x0gBQaY/CUvHFBrMHr5ObhZvN7ou6PSyBCGgQxFf5jmnwSzeBRc/iWxMBltM/SQSTAgyKWdolcgBNTOTre5z8R8FCv/CIsfLoqUFuWthrT3YfpG1iOWlL3GBm8XxXlgrmvMUhV1qvcO/1no6ZeSp8VQMiTYkvAOQ7Hd\n' ]), owner='ec2-user', mode='000400', group='ec2-user'), # setup .bashrc '/home/ec2-user/.bashrc': InitFile(content=Join( '', ['export PATH="/home/ec2-user/miniconda/bin:$PATH"\n']), owner='ec2-user', mode='000400', group='ec2-user'), # configure cfn-hup '/etc/cfn/cfn-hup.conf': InitFile(content=Join('', [ '[main]\n',
def main(): '''Function: Generates the Cloudformation template''' template = Template() template.set_description("Server Stack") keyname_param = template.add_parameter( Parameter( 'KeyName', Description='An existing EC2 KeyPair.', ConstraintDescription='An existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', ) ) template.add_mapping('RegionMap', {'eu-north-1': {'ami': 'ami-a536bedb'}, 'ap-south-1': {'ami': 'ami-00b2a5e29f669c903'}, 'eu-west-3': {'ami': 'ami-0d8581d2794d7df68'}, 'eu-west-2': {'ami': 'ami-02369579484abae2e'}, 'eu-west-1': {'ami': 'ami-0c17a2bccea3e36f9'}, 'ap-northeast-2': {'ami': 'ami-05daa9d0230f30d79'}, 'ap-northeast-1': {'ami': 'ami-03a90fe15b63befea'}, 'sa-east-1': {'ami': 'ami-0c04bf4cfbf3e9dbe'}, 'ca-central-1': {'ami': 'ami-013d2a414e834a144'}, 'ap-southeast-1': {'ami': 'ami-07ed1f021e2eea7cb'}, 'ap-southeast-2': {'ami': 'ami-068e6346d66ed62c8'}, 'eu-central-1': {'ami': 'ami-00aa61be0e9a8f948'}, 'us-east-1': {'ami': 'ami-0dd925351e231e8c7'}, 'us-east-2': {'ami': 'ami-06cb7cbcc0e8e90e8'}, 'us-west-1': {'ami': 'ami-0d8e4e7b60cd5f225'}, 'us-west-2': {'ami': 'ami-06ad92f74f2c20787'}}) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'EC2SecurityGroup', Tags=[{'Key':'Name', 'Value':Ref('AWS::StackName')},], GroupDescription='EC2 Security Group', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0', Description='SSH'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0', Description='HTTP'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0', Description='HTTPS'), ], ) ) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig( files=InitFiles({ "/tmp/instance.txt": InitFile( content=Ref('AWS::StackName'), mode="000644", owner="root", group="root" ) }), ) }), ), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal(Timeout='PT15M') ), Tags=[{'Key':'Name', 'Value':Ref('AWS::StackName')},], ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'ami'), InstanceType='t2.2xlarge', KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group)], UserData=Base64( Join( '', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n', 'unset UCF_FORCE_CONFFOLD\n', 'export UCF_FORCE_CONFFNEW=YES\n', 'ucf --purge /boot/grub/menu.lst\n', 'export DEBIAN_FRONTEND=noninteractive\n', 'apt-get update\n', 'apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy upgrade\n', 'apt-get install -y python-pip\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', '# Signal Cloudformation when set up is complete\n', '/usr/local/bin/cfn-signal -e $? --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', ] ) ) ) ) template.add_resource( ec2.EIP( 'ElasticIP', InstanceId=Ref(ec2_instance), Domain='vpc' ) ) template.add_output([ Output( 'InstanceDnsName', Description='PublicDnsName', Value=GetAtt(ec2_instance, 'PublicDnsName'), ), ]) print(template.to_yaml())
# Docker doesn't see the new block device until restarted service docker stop && service docker start systemctl start ecs # Start up the cfn-hup daemon to listen for changes # to the metadata /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup # Signal the status from cfn-init /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} \ --resource NetKANCompute --region ${AWS::Region} """) cfn_hup = InitFile( content=Sub("[main]\nstack=${AWS::StackId}\nregion=${AWS::Region}\n"), mode='000400', owner='root', group='root') reloader = InitFile(content=Sub(""" [cfn-auto-reloader-hook] triggers=post.add, post.update 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"
)) instance_metadata = Metadata( Init({ 'config': InitConfig( packages={'yum': {'httpd': []}}, commands={ 'copytest': {'command': 'cp /home/ec2-user/test.txt /var/www/html/'} }, files=InitFiles({ '/etc/cfn/cfn-hup.conf': InitFile(content=Join('', ['[main]\n', 'stack=', ref_stack_id, '\n', 'region=', ref_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.WebServerInstance.\ Metadata.AWS::CloudFormation::Init\n', 'action=/opt/aws/bin/cfn-init -v ', ' --stack ', ref_stack_name, ' --resource WebServerInstance ',
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"), ))
def main(): '''Function: Generates the Cloudformation template''' template = Template() keyname_param = template.add_parameter( Parameter( 'KeyName', Description='Name of an existing EC2 KeyPair for SSH access', ConstraintDescription='must be the name of an existing EC2 KeyPair.', Type='AWS::EC2::KeyPair::KeyName', ) ) password_param = template.add_parameter( Parameter( 'PassWord', Type='String', NoEcho=True, MinLength=8, MaxLength=64, Description='Password for the admin account', ConstraintDescription='A complex password at least eight chars long with alphanumeric characters, dashes and underscores.', AllowedPattern="[-_a-zA-Z0-9]*", ) ) ec2_security_group = template.add_resource( ec2.SecurityGroup( 'SecurityGroup', GroupDescription='SSH, HTTP/HTTPS open for 0.0.0.0/0', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp='0.0.0.0/0'), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), ], ) ) ec2_instance = template.add_resource( ec2.Instance( 'Instance', Metadata=Metadata( Init({ "config": InitConfig( files=InitFiles({ "/etc/nginx/conf.d/app.conf": InitFile( content='server { listen 80 default_server; listen [::]:80 default_server; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }', mode="000644", owner="root", group="root" ) }), ) }), ), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=[{'Key':'Name', 'Value':'Simple Stack Instance {}'.format(time.strftime('%c'))},], ImageId='ami-39c28c41', InstanceType='t2.micro', KeyName=Ref(keyname_param), SecurityGroups=[Ref(ec2_security_group)], UserData=Base64( Join( '', [ '#!/bin/bash -x\n', 'exec > /tmp/user-data.log 2>&1\n' 'apt-get update\n', 'apt-get install -y python-pip\n', 'pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n', 'apt-get install -y nginx\n', 'apt-get install -y openjdk-8-jdk\n', '/usr/local/bin/cfn-init --verbose --resource=Instance --region=', Ref('AWS::Region'), ' --stack=', Ref('AWS::StackName'), '\n', 'unlink /etc/nginx/sites-enabled/default\n' 'systemctl reload nginx\n', '/usr/local/bin/cfn-signal -e 0 --resource Instance --region us-west-2 --stack simple\n', ] ) ) ) ) template.add_output([ Output( 'PublicDnsName', Description='PublicDnsName', Value=GetAtt(ec2_instance, 'PublicDnsName'), ), ]) print(template.to_yaml())
'ContainerInstances', Metadata=Metadata( Init({ 'config': InitConfig( files=InitFiles( { '/etc/cfn/cfn-hup.conf': InitFile( content=Join( '', [ '[main]\n', 'stack=', Ref('AWS::StackId'), # NOQA '\n', 'region=', Ref('AWS::Region'), '\n' ]), # NOQA 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.ContainerInstances.Metadata.AWS::CloudFormation::Init\n', # NOQA
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())