def get_instance_metadata(instance_name): return autoscaling.Metadata( cfn.Init({ 'config': cfn.InitConfig( packages={'yum': { 'httpd': [] }}, files=cfn.InitFiles({ '/etc/cfn/cfn-hup.conf': cfn.InitFile(content=Join('', [ '[main]\n', 'stack=', Ref('AWS::StackName'), '\n', 'region=', Ref('AWS::Region'), '\n', ]), mode='000400', owner='root', group='root'), '/etc/cfn/hooks.d/cfn-auto-reloader.conf': cfn.InitFile(content=Join('', [ '[cfn-auto-reloader-hook]\n', 'triggers=post.update\n', 'path=Resources.', instance_name, '.Metadata.AWS::CloudFormation::Init\n', 'action=/opt/aws/bin/cfn-init -v ', ' --stack=', Ref('AWS::StackName'), ' --resource=', instance_name, ' --region=', Ref('AWS::Region'), '\n', 'runas=root\n', ])) }), services={ 'sysvinit': cfn.InitServices({ 'httpd': cfn.InitService(enabled=True, ensureRunning=True), 'cfn-hup': cfn.InitService( enabled=True, ensureRunning=True, files=[ '/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/cfn-auto-reloader.conf' ]) }) }) }))
def configure_for_follower(instance, counter): subnet_index = counter % NUM_AZS if counter == 2: instance.DependsOn = "MonitorInstance" else: instance.DependsOn = BASE_NAME + str(counter - 1) #base_instance.title instance.SubnetId = Select(str(subnet_index), Ref(PrivateSubnetsToSpanParam)) # instance.AvailabilityZone = Select(str(subnet_index), Ref(AvailabilityZonesParam)) instance.Metadata = cloudformation.Metadata( cloudformation.Authentication({ "S3AccessCreds": cloudformation.AuthenticationBlock( type="S3", roleName=Ref(StorReduceHostRole), #Ref(HostRoleParam), buckets=[Ref(QSS3BucketNameParam)]) }), cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/home/ec2-user/connect-srr.sh": cloudformation.InitFile(source=Sub( "https://${" + QSS3BucketNameParam.title + "}.${QSS3Region}.amazonaws.com/${" + QSS3KeyPrefixParam.title + "}scripts/connect-srr.sh", **{ "QSS3Region": If("GovCloudCondition", "s3-us-gov-west-1", "s3") }), mode="000550", owner="root", group="root") }), commands={ "connect-srr": { "command": Join("", [ "/home/ec2-user/connect-srr.sh \"", GetAtt(base_instance, "PrivateDnsName"), "\" \'", Ref(StorReducePasswordParam), "\' ", "\"", Ref(ShardsNumParam), "\" ", "\"", Ref(ReplicaShardsNumParam), "\" ", "\"", Ref(elasticLB), "\" ", "\"", Ref("AWS::Region"), "\" ", "\"", GetAtt("Eth0", "PrimaryPrivateIpAddress"), "\" ", "\"", Ref(NumSRRHostsParam), "\"" ]) } }) })) instance.Tags = [{"Key": "Name", "Value": "StorReduce-QS-Host"}]
def _add_ec2_auto_scaling(self): instance_profile = self._add_instance_profile() self.sg_alb = SecurityGroup( "SecurityGroupAlb", VpcId=Ref(self.vpc), GroupDescription=Sub("${AWS::StackName}-alb")) self.template.add_resource(self.sg_alb) self.sg_hosts = SecurityGroup( "SecurityGroupEc2Hosts", SecurityGroupIngress=[{ 'SourceSecurityGroupId': Ref(self.sg_alb), 'IpProtocol': -1 }], VpcId=Ref(self.vpc), GroupDescription=Sub("${AWS::StackName}-hosts")) self.template.add_resource(self.sg_hosts) sg_host_ingress = SecurityGroupIngress("SecurityEc2HostsIngress", SourceSecurityGroupId=Ref( self.sg_hosts), IpProtocol="-1", GroupId=Ref(self.sg_hosts), FromPort="-1", ToPort="-1") self.template.add_resource(sg_host_ingress) database_security_group = SecurityGroup( "SecurityGroupDatabases", SecurityGroupIngress=[{ 'SourceSecurityGroupId': Ref(self.sg_hosts), 'IpProtocol': -1 }], VpcId=Ref(self.vpc), GroupDescription=Sub("${AWS::StackName}-databases")) self.template.add_resource(database_security_group) user_data = Base64( Sub('\n'.join([ "#!/bin/bash", "yum update -y", "yum install -y aws-cfn-bootstrap", "/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration", "/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup", "yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm", "systemctl enable amazon-ssm-agent", "systemctl start amazon-ssm-agent", "" ]))) lc_metadata = cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/etc/cfn/cfn-hup.conf": cloudformation.InitFile( content=Sub('\n'.join([ '[main]', 'stack=${AWS::StackId}', 'region=${AWS::Region}', '' ])), mode='256', # TODO: Why 256 owner="root", group="root"), "/etc/cfn/hooks.d/cfn-auto-reloader.conf": cloudformation.InitFile(content=Sub('\n'.join([ '[cfn-auto-reloader-hook]', 'triggers=post.update', 'path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init', 'action=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration', '' ])), ) }), services={ "sysvinit": cloudformation.InitServices({ "cfn-hup": cloudformation.InitService( enabled=True, ensureRunning=True, files=[ '/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/cfn-auto-reloader.conf' ]) }) }, commands={ '01_add_instance_to_cluster': { 'command': Sub('echo "ECS_CLUSTER=${Cluster}\nECS_RESERVED_MEMORY=256" > /etc/ecs/ecs.config' ) } }) }) launch_configuration = LaunchConfiguration( 'LaunchConfiguration', UserData=user_data, IamInstanceProfile=Ref(instance_profile), SecurityGroups=[Ref(self.sg_hosts)], InstanceType=Ref('InstanceType'), ImageId=FindInMap("AWSRegionToAMI", Ref("AWS::Region"), "AMI"), Metadata=lc_metadata, KeyName=Ref(self.key_pair)) self.template.add_resource(launch_configuration) # , PauseTime='PT15M', WaitOnResourceSignals=True, MaxBatchSize=1, MinInstancesInService=1) up = AutoScalingRollingUpdate('AutoScalingRollingUpdate') # TODO: clean up subnets = list(self.private_subnets) self.auto_scaling_group = AutoScalingGroup( "AutoScalingGroup", UpdatePolicy=up, DesiredCapacity=self.desired_instances, Tags=[{ 'PropagateAtLaunch': True, 'Value': Sub('${AWS::StackName} - ECS Host'), 'Key': 'Name' }], MinSize=Ref('MinSize'), MaxSize=Ref('MaxSize'), VPCZoneIdentifier=[Ref(subnets.pop()), Ref(subnets.pop())], LaunchConfigurationName=Ref(launch_configuration), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M'))) self.template.add_resource(self.auto_scaling_group) self.cluster_scaling_policy = ScalingPolicy( 'AutoScalingPolicy', AdjustmentType='ChangeInCapacity', AutoScalingGroupName=Ref(self.auto_scaling_group), Cooldown=300, PolicyType='SimpleScaling', ScalingAdjustment=1) self.template.add_resource(self.cluster_scaling_policy)
def main(): """ Create a ElastiCache Redis Node and EC2 Instance """ template = Template() # Description template.set_description( 'AWS CloudFormation Sample Template ElastiCache_Redis:' 'Sample template showing how to create an Amazon' 'ElastiCache Redis Cluster. **WARNING** This template' 'creates an Amazon EC2 Instance and an Amazon ElastiCache' 'Cluster. You will be billed for the AWS resources used' 'if you create a stack from this template.') # Mappings template.add_mapping('AWSInstanceType2Arch', { 't1.micro': {'Arch': 'PV64'}, 't2.micro': {'Arch': 'HVM64'}, 't2.small': {'Arch': 'HVM64'}, 't2.medium': {'Arch': 'HVM64'}, 'm1.small': {'Arch': 'PV64'}, 'm1.medium': {'Arch': 'PV64'}, 'm1.large': {'Arch': 'PV64'}, 'm1.xlarge': {'Arch': 'PV64'}, 'm2.xlarge': {'Arch': 'PV64'}, 'm2.2xlarge': {'Arch': 'PV64'}, 'm2.4xlarge': {'Arch': 'PV64'}, 'm3.medium': {'Arch': 'HVM64'}, 'm3.large': {'Arch': 'HVM64'}, 'm3.xlarge': {'Arch': 'HVM64'}, 'm3.2xlarge': {'Arch': 'HVM64'}, 'c1.medium': {'Arch': 'PV64'}, 'c1.xlarge': {'Arch': 'PV64'}, 'c3.large': {'Arch': 'HVM64'}, 'c3.xlarge': {'Arch': 'HVM64'}, 'c3.2xlarge': {'Arch': 'HVM64'}, 'c3.4xlarge': {'Arch': 'HVM64'}, 'c3.8xlarge': {'Arch': 'HVM64'}, 'c4.large': {'Arch': 'HVM64'}, 'c4.xlarge': {'Arch': 'HVM64'}, 'c4.2xlarge': {'Arch': 'HVM64'}, 'c4.4xlarge': {'Arch': 'HVM64'}, 'c4.8xlarge': {'Arch': 'HVM64'}, 'g2.2xlarge': {'Arch': 'HVMG2'}, 'r3.large': {'Arch': 'HVM64'}, 'r3.xlarge': {'Arch': 'HVM64'}, 'r3.2xlarge': {'Arch': 'HVM64'}, 'r3.4xlarge': {'Arch': 'HVM64'}, 'r3.8xlarge': {'Arch': 'HVM64'}, 'i2.xlarge': {'Arch': 'HVM64'}, 'i2.2xlarge': {'Arch': 'HVM64'}, 'i2.4xlarge': {'Arch': 'HVM64'}, 'i2.8xlarge': {'Arch': 'HVM64'}, 'd2.xlarge': {'Arch': 'HVM64'}, 'd2.2xlarge': {'Arch': 'HVM64'}, 'd2.4xlarge': {'Arch': 'HVM64'}, 'd2.8xlarge': {'Arch': 'HVM64'}, 'hi1.4xlarge': {'Arch': 'HVM64'}, 'hs1.8xlarge': {'Arch': 'HVM64'}, 'cr1.8xlarge': {'Arch': 'HVM64'}, 'cc2.8xlarge': {'Arch': 'HVM64'} }) template.add_mapping('AWSRegionArch2AMI', { 'us-east-1': {'PV64': 'ami-0f4cfd64', 'HVM64': 'ami-0d4cfd66', 'HVMG2': 'ami-5b05ba30'}, 'us-west-2': {'PV64': 'ami-d3c5d1e3', 'HVM64': 'ami-d5c5d1e5', 'HVMG2': 'ami-a9d6c099'}, 'us-west-1': {'PV64': 'ami-85ea13c1', 'HVM64': 'ami-87ea13c3', 'HVMG2': 'ami-37827a73'}, 'eu-west-1': {'PV64': 'ami-d6d18ea1', 'HVM64': 'ami-e4d18e93', 'HVMG2': 'ami-72a9f105'}, 'eu-central-1': {'PV64': 'ami-a4b0b7b9', 'HVM64': 'ami-a6b0b7bb', 'HVMG2': 'ami-a6c9cfbb'}, 'ap-northeast-1': {'PV64': 'ami-1a1b9f1a', 'HVM64': 'ami-1c1b9f1c', 'HVMG2': 'ami-f644c4f6'}, 'ap-southeast-1': {'PV64': 'ami-d24b4280', 'HVM64': 'ami-d44b4286', 'HVMG2': 'ami-12b5bc40'}, 'ap-southeast-2': {'PV64': 'ami-ef7b39d5', 'HVM64': 'ami-db7b39e1', 'HVMG2': 'ami-b3337e89'}, 'sa-east-1': {'PV64': 'ami-5b098146', 'HVM64': 'ami-55098148', 'HVMG2': 'NOT_SUPPORTED'}, 'cn-north-1': {'PV64': 'ami-bec45887', 'HVM64': 'ami-bcc45885', 'HVMG2': 'NOT_SUPPORTED'} }) template.add_mapping('Region2Principal', { 'us-east-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'us-west-2': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'us-west-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'eu-west-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'ap-southeast-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'ap-northeast-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'ap-southeast-2': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'sa-east-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'}, 'cn-north-1': {'EC2Principal': 'ec2.amazonaws.com.cn', 'OpsWorksPrincipal': 'opsworks.amazonaws.com.cn'}, 'eu-central-1': {'EC2Principal': 'ec2.amazonaws.com', 'OpsWorksPrincipal': 'opsworks.amazonaws.com'} }) # Parameters cachenodetype = template.add_parameter(Parameter( 'ClusterNodeType', Description='The compute and memory capacity of the nodes in the Redis' ' Cluster', Type='String', Default='cache.m1.small', AllowedValues=['cache.m1.small', 'cache.m1.large', 'cache.m1.xlarge', 'cache.m2.xlarge', 'cache.m2.2xlarge', 'cache.m2.4xlarge', 'cache.c1.xlarge'], ConstraintDescription='must select a valid Cache Node type.', )) instancetype = template.add_parameter(Parameter( 'InstanceType', Description='WebServer EC2 instance type', Type='String', Default='t2.micro', 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', '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.', )) keyname = template.add_parameter(Parameter( 'KeyName', Description='Name of an existing EC2 KeyPair to enable SSH access' ' to the instance', Type='AWS::EC2::KeyPair::KeyName', ConstraintDescription='must be the name of an existing EC2 KeyPair.', )) sshlocation = template.add_parameter(Parameter( 'SSHLocation', Description='The IP address range that can be used to SSH to' ' the EC2 instances', Type='String', MinLength='9', MaxLength='18', Default='0.0.0.0/0', AllowedPattern='(\\d{1,3})\\.(\\d{1,3})\\.' '(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})', ConstraintDescription='must be a valid IP CIDR range of the' ' form x.x.x.x/x.' )) # Resources webserverrole = template.add_resource(iam.Role( 'WebServerRole', AssumeRolePolicyDocument=PolicyDocument( Statement=[ Statement( Effect=Allow, Action=[AssumeRole], Principal=Principal('Service', [FindInMap('Region2Principal', Ref('AWS::Region'), 'EC2Principal')]), ) ] ), Path='/', )) template.add_resource(iam.PolicyType( 'WebServerRolePolicy', PolicyName='WebServerRole', PolicyDocument=PolicyDocument( Statement=[awacs.aws.Statement( Action=[awacs.aws.Action("elasticache", "DescribeCacheClusters")], Resource=["*"], Effect=awacs.aws.Allow )] ), Roles=[Ref(webserverrole)], )) webserverinstanceprofile = template.add_resource(iam.InstanceProfile( 'WebServerInstanceProfile', Path='/', Roles=[Ref(webserverrole)], )) webserversg = template.add_resource(ec2.SecurityGroup( 'WebServerSecurityGroup', GroupDescription='Enable HTTP and SSH access', SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp=Ref(sshlocation), ), ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0', ) ] )) webserverinstance = template.add_resource(ec2.Instance( 'WebServerInstance', Metadata=cloudformation.Metadata( cloudformation.Init({ 'config': cloudformation.InitConfig( packages={ 'yum': { 'httpd': [], 'php': [], 'php-devel': [], 'gcc': [], 'make': [] } }, files=cloudformation.InitFiles({ '/var/www/html/index.php': cloudformation.InitFile( content=Join('', [ '<?php\n', 'echo \"<h1>AWS CloudFormation sample' ' application for Amazon ElastiCache' ' Redis Cluster</h1>\";\n', '\n', '$cluster_config = json_decode(' 'file_get_contents(\'/tmp/cacheclusterconfig\'' '), true);\n', '$endpoint = $cluster_config[\'CacheClusters' '\'][0][\'CacheNodes\'][0][\'Endpoint\'][\'Add' 'ress\'];\n', '$port = $cluster_config[\'CacheClusters\'][0]' '[\'CacheNodes\'][0][\'Endpoint\'][\'Port\'];' '\n', '\n', 'echo \"<p>Connecting to Redis Cache Cluster ' 'node \'{$endpoint}\' on port {$port}</p>\";' '\n', '\n', '$redis=new Redis();\n', '$redis->connect($endpoint, $port);\n', '$redis->set(\'testkey\', \'Hello World!\');' '\n', '$return = $redis->get(\'testkey\');\n', '\n', 'echo \"<p>Retrieved value: $return</p>\";' '\n', '?>\n' ]), mode='000644', owner='apache', group='apache' ), '/etc/cron.d/get_cluster_config': cloudformation.InitFile( content='*/5 * * * * root' ' /usr/local/bin/get_cluster_config', mode='000644', owner='root', group='root' ), '/usr/local/bin/get_cluster_config': cloudformation.InitFile( content=Join('', [ '#! /bin/bash\n', 'aws elasticache describe-cache-clusters ', ' --cache-cluster-id ', Ref('RedisCluster'), ' --show-cache-node-info' ' --region ', Ref('AWS::Region'), ' > /tmp/cacheclusterconfig\n' ]), mode='000755', owner='root', group='root' ), '/usr/local/bin/install_phpredis': cloudformation.InitFile( content=Join('', [ '#! /bin/bash\n', 'cd /tmp\n', 'wget https://github.com/nicolasff/' 'phpredis/zipball/master -O phpredis.zip' '\n', 'unzip phpredis.zip\n', 'cd nicolasff-phpredis-*\n', 'phpize\n', './configure\n', 'make && make install\n', 'touch /etc/php.d/redis.ini\n', 'echo extension=redis.so > /etc/php.d/' 'redis.ini\n' ]), mode='000755', owner='root', group='root' ), '/etc/cfn/cfn-hup.conf': cloudformation.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': cloudformation.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('AWS::StackName'), ' --resource WebServerInstance ', ' --region ', Ref('AWS::Region'), '\n', 'runas=root\n' ]), # Why doesn't the Amazon template have this? # mode='000400', # owner='root', # group='root' ), }), commands={ '01-install_phpredis': { 'command': '/usr/local/bin/install_phpredis' }, '02-get-cluster-config': { 'command': '/usr/local/bin/get_cluster_config' } }, services={ "sysvinit": cloudformation.InitServices({ "httpd": cloudformation.InitService( enabled=True, ensureRunning=True, ), "cfn-hup": cloudformation.InitService( enabled=True, ensureRunning=True, files=['/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/' 'cfn-auto-reloader.conf'] ), }), }, ) }) ), ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'), FindInMap('AWSInstanceType2Arch', Ref(instancetype), 'Arch')), InstanceType=Ref(instancetype), SecurityGroups=[Ref(webserversg)], KeyName=Ref(keyname), IamInstanceProfile=Ref(webserverinstanceprofile), UserData=Base64(Join('', [ '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n', '# Setup the PHP sample application\n', '/opt/aws/bin/cfn-init -v ', ' --stack ', Ref('AWS::StackName'), ' --resource WebServerInstance ', ' --region ', Ref('AWS::Region'), '\n', '# Signal the status of cfn-init\n', '/opt/aws/bin/cfn-signal -e $? ', ' --stack ', Ref('AWS::StackName'), ' --resource WebServerInstance ', ' --region ', Ref('AWS::Region'), '\n' ])), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal(Timeout='PT15M') ), Tags=Tags(Application=Ref('AWS::StackId'), Details='Created using Troposhpere') )) redisclustersg = template.add_resource(elasticache.SecurityGroup( 'RedisClusterSecurityGroup', Description='Lock the cluster down', )) template.add_resource(elasticache.SecurityGroupIngress( 'RedisClusterSecurityGroupIngress', CacheSecurityGroupName=Ref(redisclustersg), EC2SecurityGroupName=Ref(webserversg), )) template.add_resource(elasticache.CacheCluster( 'RedisCluster', Engine='redis', CacheNodeType=Ref(cachenodetype), NumCacheNodes='1', CacheSecurityGroupNames=[Ref(redisclustersg)], )) # Outputs template.add_output([ Output( 'WebsiteURL', Description='Application URL', Value=Join('', [ 'http://', GetAtt(webserverinstance, 'PublicDnsName'), ]) ) ]) # Print CloudFormation Template print(template.to_json())
def buildStack(bootstrap, env): t = Template() t.add_description("""\ Configures autoscaling group for hello world app""") vpcCidr = t.add_parameter( Parameter( "VPCCidr", Type="String", Description="VPC cidr (x.x.x.x/xx)", )) publicSubnet1 = t.add_parameter( Parameter( "PublicSubnet1", Type="String", Description="A public VPC subnet ID for the api app load balancer.", )) publicSubnet2 = t.add_parameter( Parameter( "PublicSubnet2", Type="String", Description="A public VPC subnet ID for the api load balancer.", )) dbName = t.add_parameter( Parameter( "DBName", Default="HelloWorldApp", Description="The database name", Type="String", MinLength="1", MaxLength="64", AllowedPattern="[a-zA-Z][a-zA-Z0-9]*", ConstraintDescription=("must begin with a letter and contain only" " alphanumeric characters."))) dbUser = t.add_parameter( Parameter( "DBUser", NoEcho=True, Description="The database admin account username", Type="String", MinLength="1", MaxLength="16", AllowedPattern="[a-zA-Z][a-zA-Z0-9]*", ConstraintDescription=("must begin with a letter and contain only" " alphanumeric characters."))) dbPassword = t.add_parameter( Parameter( "DBPassword", NoEcho=True, Description="The database admin account password", Type="String", MinLength="8", MaxLength="41", AllowedPattern="[a-zA-Z0-9]*", ConstraintDescription="must contain only alphanumeric characters.") ) dbType = t.add_parameter( Parameter( "DBType", Default="db.t2.medium", Description="Database instance class", Type="String", AllowedValues=[ "db.m5.large", "db.m5.xlarge", "db.m5.2xlarge", "db.m5.4xlarge", "db.m5.12xlarge", "db.m5.24xlarge", "db.m4.large", "db.m4.xlarge", "db.m4.2xlarge", "db.m4.4xlarge", "db.m4.10xlarge", "db.m4.16xlarge", "db.r4.large", "db.r4.xlarge", "db.r4.2xlarge", "db.r4.4xlarge", "db.r4.8xlarge", "db.r4.16xlarge", "db.x1e.xlarge", "db.x1e.2xlarge", "db.x1e.4xlarge", "db.x1e.8xlarge", "db.x1e.16xlarge", "db.x1e.32xlarge", "db.x1.16xlarge", "db.x1.32xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.t2.micro", "db.t2.small", "db.t2.medium", "db.t2.large", "db.t2.xlarge", "db.t2.2xlarge" ], ConstraintDescription="must select a valid database instance type.", )) dbAllocatedStorage = t.add_parameter( Parameter( "DBAllocatedStorage", Default="5", Description="The size of the database (Gb)", Type="Number", MinValue="5", MaxValue="1024", ConstraintDescription="must be between 5 and 1024Gb.", )) whitelistedCIDR = t.add_parameter( Parameter( "WhitelistedCIDR", Description="CIDR whitelisted to be open on public instances", Type="String", )) #### NETWORK SECTION #### vpc = t.add_resource( VPC("VPC", CidrBlock=Ref(vpcCidr), EnableDnsHostnames=True)) subnet1 = t.add_resource( Subnet("Subnet1", CidrBlock=Ref(publicSubnet1), AvailabilityZone="eu-west-1a", VpcId=Ref(vpc))) subnet2 = t.add_resource( Subnet("Subnet2", CidrBlock=Ref(publicSubnet2), AvailabilityZone="eu-west-1b", VpcId=Ref(vpc))) internetGateway = t.add_resource(InternetGateway('InternetGateway')) gatewayAttachment = t.add_resource( VPCGatewayAttachment('AttachGateway', VpcId=Ref(vpc), InternetGatewayId=Ref(internetGateway))) routeTable = t.add_resource(RouteTable('RouteTable', VpcId=Ref(vpc))) route = t.add_resource( Route( 'Route', DependsOn='AttachGateway', GatewayId=Ref('InternetGateway'), DestinationCidrBlock='0.0.0.0/0', RouteTableId=Ref(routeTable), )) subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociation', SubnetId=Ref(subnet1), RouteTableId=Ref(routeTable), )) subnetRouteTableAssociation2 = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociation2', SubnetId=Ref(subnet2), RouteTableId=Ref(routeTable), )) #### SECURITY GROUP #### loadBalancerSg = t.add_resource( ec2.SecurityGroup( "LoadBalancerSecurityGroup", VpcId=Ref(vpc), GroupDescription="Enable SSH access via port 22", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="80", ToPort="80", CidrIp="0.0.0.0/0", ), ], )) instanceSg = t.add_resource( ec2.SecurityGroup( "InstanceSecurityGroup", VpcId=Ref(vpc), GroupDescription="Enable SSH access via port 22", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", CidrIp=Ref(whitelistedCIDR), ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="8000", ToPort="8000", SourceSecurityGroupId=Ref(loadBalancerSg), ), ], )) rdsSg = t.add_resource( SecurityGroup("RDSSecurityGroup", GroupDescription="Security group for RDS DB Instance.", VpcId=Ref(vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="5432", ToPort="5432", SourceSecurityGroupId=Ref(instanceSg), ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="5432", ToPort="5432", CidrIp=Ref(whitelistedCIDR), ), ])) #### DATABASE SECTION #### subnetGroup = t.add_resource( DBSubnetGroup( "SubnetGroup", DBSubnetGroupDescription= "Subnets available for the RDS DB Instance", SubnetIds=[Ref(subnet1), Ref(subnet2)], )) db = t.add_resource( DBInstance( "RDSHelloWorldApp", DBName=Join("", [Ref(dbName), env]), DBInstanceIdentifier=Join("", [Ref(dbName), env]), EnableIAMDatabaseAuthentication=True, PubliclyAccessible=True, AllocatedStorage=Ref(dbAllocatedStorage), DBInstanceClass=Ref(dbType), Engine="postgres", EngineVersion="10.4", MasterUsername=Ref(dbUser), MasterUserPassword=Ref(dbPassword), DBSubnetGroupName=Ref(subnetGroup), VPCSecurityGroups=[Ref(rdsSg)], )) t.add_output( Output("RDSConnectionString", Description="Connection string for database", Value=GetAtt("RDSHelloWorldApp", "Endpoint.Address"))) if (bootstrap): return t #### INSTANCE SECTION #### keyName = t.add_parameter( Parameter( "KeyName", Type="String", Description="Name of an existing EC2 KeyPair to enable SSH access", MinLength="1", AllowedPattern="[\x20-\x7E]*", MaxLength="255", ConstraintDescription="can contain only ASCII characters.", )) scaleCapacityMin = t.add_parameter( Parameter( "ScaleCapacityMin", Default="1", Type="String", Description="Number of api servers to run", )) scaleCapacityMax = t.add_parameter( Parameter( "ScaleCapacityMax", Default="1", Type="String", Description="Number of api servers to run", )) scaleCapacityDesired = t.add_parameter( Parameter( "ScaleCapacityDesired", Default="1", Type="String", Description="Number of api servers to run", )) amiId = t.add_parameter( Parameter( "AmiId", Type="String", Default="ami-09693313102a30b2c", Description="The AMI id for the api instances", )) instanceType = t.add_parameter( Parameter("InstanceType", Description="WebServer EC2 instance type", Type="String", Default="t2.medium", AllowedValues=[ "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge" ], ConstraintDescription="must be a valid EC2 instance type.")) assumeRole = t.add_resource( Role("AssumeRole", AssumeRolePolicyDocument=json.loads("""\ { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }\ """))) instanceProfile = t.add_resource( InstanceProfile("InstanceProfile", Roles=[Ref(assumeRole)])) rolePolicyType = t.add_resource( PolicyType("RolePolicyType", Roles=[Ref(assumeRole)], PolicyName=Join("", ["CloudWatchHelloWorld", "-", env]), PolicyDocument=json.loads("""\ { "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": [ "arn:aws:logs:*:*:*" ] } ] }\ """))) appPassword = t.add_parameter( Parameter( "AppPassword", NoEcho=True, Description="The Password for the app user", Type="String", MinLength="8", MaxLength="41", AllowedPattern="[a-zA-Z0-9]*", ConstraintDescription="must contain only alphanumeric characters.") ) launchConfig = t.add_resource( LaunchConfiguration( "LaunchConfiguration", Metadata=autoscaling.Metadata( cloudformation.Init({ "config": cloudformation.InitConfig(files=cloudformation.InitFiles({ "/home/app/environment": cloudformation.InitFile(content=Join( "", [ "SPRING_DATASOURCE_URL=", "jdbc:postgresql://", GetAtt("RDSHelloWorldApp", "Endpoint.Address"), ":5432/HelloWorldApp" + env + "?currentSchema=hello_world", "\n", "SPRING_DATASOURCE_USERNAME=app", "\n", "SPRING_DATASOURCE_PASSWORD="******"\n", "SPRING_PROFILES_ACTIVE=", env, "\n" ]), mode="000600", owner="app", group="app") }), ) }), ), UserData=Base64( Join('', [ "#!/bin/bash\n", "/opt/aws/bin/cfn-init", " --resource LaunchConfiguration", " --stack ", Ref("AWS::StackName"), " --region ", Ref("AWS::Region"), "\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref": "AWS::StackName" }, " --resource AutoscalingGroup ", " --region ", { "Ref": "AWS::Region" }, "\n" ])), ImageId=Ref(amiId), KeyName=Ref(keyName), IamInstanceProfile=Ref(instanceProfile), BlockDeviceMappings=[ ec2.BlockDeviceMapping(DeviceName="/dev/xvda", Ebs=ec2.EBSBlockDevice(VolumeSize="8")), ], SecurityGroups=[Ref(instanceSg)], InstanceType=Ref(instanceType), AssociatePublicIpAddress='True', )) applicationElasticLB = t.add_resource( elb.LoadBalancer("ApplicationElasticLB", Name="ApplicationElasticLB-" + env, Scheme="internet-facing", Type="application", SecurityGroups=[Ref(loadBalancerSg)], Subnets=[Ref(subnet1), Ref(subnet2)])) targetGroup = t.add_resource( elb.TargetGroup("TargetGroupHelloWorld", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="15", HealthyThresholdCount="5", Matcher=elb.Matcher(HttpCode="200,404"), Port="8000", Protocol="HTTP", UnhealthyThresholdCount="3", TargetGroupAttributes=[ elb.TargetGroupAttribute( Key="deregistration_delay.timeout_seconds", Value="120", ) ], VpcId=Ref(vpc))) listener = t.add_resource( elb.Listener("Listener", Port="80", Protocol="HTTP", LoadBalancerArn=Ref(applicationElasticLB), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(targetGroup)) ])) t.add_output( Output("URL", Description="URL of the sample website", Value=Join("", ["http://", GetAtt(applicationElasticLB, "DNSName")]))) autoScalingGroup = t.add_resource( AutoScalingGroup( "AutoscalingGroup", DesiredCapacity=Ref(scaleCapacityDesired), LaunchConfigurationName=Ref(launchConfig), MinSize=Ref(scaleCapacityMin), MaxSize=Ref(scaleCapacityMax), VPCZoneIdentifier=[Ref(subnet1), Ref(subnet2)], TargetGroupARNs=[Ref(targetGroup)], HealthCheckType="ELB", HealthCheckGracePeriod=360, UpdatePolicy=UpdatePolicy( AutoScalingReplacingUpdate=AutoScalingReplacingUpdate( WillReplace=True, ), AutoScalingRollingUpdate=AutoScalingRollingUpdate( PauseTime='PT5M', MinInstancesInService="1", MaxBatchSize='1', WaitOnResourceSignals=True)), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout="PT15M", Count=Ref(scaleCapacityDesired))))) # print(t.to_json()) return t
def _launch_config(self): return LaunchConfiguration( "LaunchConfiguration", Metadata=autoscaling.Metadata( cloudformation.Init({ "config": cloudformation.InitConfig(files=cloudformation.InitFiles({ '/etc/cfn/cfn-hup.conf': cloudformation.InitFile(content=Join( '', [ '[main]\n', 'stack=', self.ref_stack_id, '\n', 'region=', self.ref_region, '\n', ]), mode='000400', owner='root', group='root'), '/etc/cfn/hooks.d/cfn-auto-reloader.conf': cloudformation.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 ', self.ref_stack_name, ' --resource WebServerInstance ', ' --region ', self.ref_region, '\n', 'runas=root\n', ])) }), services={ "sysvinit": cloudformation.InitServices({ "rsyslog": cloudformation. InitService( enabled=True, ensureRunning=True, files=[ '/etc/rsyslog.d/20-somethin.conf' ]) }) }) })), UserData=Base64(Join('', self.config['app_instance_user_data'])), ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), KeyName=self.config['sshkey'], IamInstanceProfile=Ref(self.instance_iam_role_instance_profile), BlockDeviceMappings=[ ec2.BlockDeviceMapping(DeviceName=self.config['device_name'], Ebs=ec2.EBSBlockDevice(VolumeSize="8")), ], SecurityGroups=self.config['app_sg'], InstanceType=self.config['instance_type'], )
def generate_stack_template(): template = Template() generate_description(template) generate_version(template) # ---Parameters------------------------------------------------------------ param_vpc_id = Parameter( 'VpcIdentifer', Description= 'The identity of the VPC (vpc-abcdwxyz) in which this stack shall be created.', Type='AWS::EC2::VPC::Id', ) template.add_parameter(param_vpc_id) param_vpc_security_group = Parameter( 'VpcSecurityGroup', Description= 'The security group (sg-abcdwxyz) to apply to the resources created by this stack.', Type='AWS::EC2::SecurityGroup::Id', ) template.add_parameter(param_vpc_security_group) param_webserver_instance_subnet_id = Parameter( 'VpcSubnetIdentifer', Description= 'The identity of the public subnet (subnet-abcdwxyz) in which the web server shall be created.', Type='AWS::EC2::Subnet::Id', ) template.add_parameter(param_webserver_instance_subnet_id) param_keyname = Parameter( 'PemKeyName', Description= 'Name of an existing EC2 KeyPair file (.pem) to use to create EC2 instances', Type='AWS::EC2::KeyPair::KeyName') template.add_parameter(param_keyname) param_instance_type = Parameter( 'EC2InstanceType', Description= 'EC2 instance type, reference this parameter to insure consistency', Type='String', Default= 't2.medium', # Prices from (2015-12-03) (Windows, us-west (North CA)) AllowedValues=[ # Source : https://aws.amazon.com/ec2/pricing/ 't2.small', # $0.044/hour 't2.micro', # $0.022/hour 't2.medium', # $0.088/hour 't2.large', # $0.166/hour 'm3.medium', # $0.140/hour 'm3.large', # $0.28/hour 'c4.large' # $0.221/hour ], ConstraintDescription='Must be a valid EC2 instance type') template.add_parameter(param_instance_type) #---Mappings--------------------------------------------------------------- mapping_environment_attribute_map = template.add_mapping( 'EnvironmentAttributeMap', { 'ap-southeast-1': { 'WebServerAmi': 'ami-1ddc0b7e' }, 'ap-southeast-2': { 'WebServerAmi': 'ami-0c95b86f' }, 'us-east-1': { 'WebServerAmi': 'ami-a4827dc9' }, 'us-west-1': { 'WebServerAmi': 'ami-f5f41398' } }) # ---Resources------------------------------------------------------------- ref_region = Ref('AWS::Region') ref_stack_name = Ref('AWS::StackName') # Create the metadata for the server instance. name_web_server = 'WebServer' webserver_instance_metadata = cloudformation.Metadata( cloudformation.Init({ 'config': cloudformation.InitConfig( packages={'yum': { 'nginx': [], 'git': [] }}, files=cloudformation.InitFiles({ # cfn-hup.conf initialization '/etc/cfn/authorapp.conf': cloudformation.InitFile(content=Join( '', [ 'server {', '\n', ' listen 3030 ssl http2;', '\n', ' root /var/www/authorapp;', '\n', '\n', ' ssl_certificate /vagrant/ssl/ca.crt;', '\n', ' ssl_certificate_key /vagrant/ssl/ca.key;', '\n', '\n', ' location / {', '\n', ' }', '\n', '\n', ' location /api {', '\n', ' proxy_pass http://10.50.50.1:3000;', '\n', ' }', '\n', '}', '\n', ]), mode='000400', owner='root', group='root'), }), services=dict(sysvinit=cloudformation.InitServices({ # start cfn-hup service - # required for CloudFormation stack update 'cfn-hup': cloudformation.InitService( enabled=True, ensureRunning=True, files=[ '/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/cfn-auto-reloader.conf' ]), # Disable sendmail service - not required. 'sendmail': cloudformation.InitService(enabled=False, ensureRunning=False) }))) })) resource_web_server = ec2.Instance( name_web_server, Metadata=webserver_instance_metadata, ImageId=FindInMap('EnvironmentAttributeMap', ref_region, 'WebServerAmi'), InstanceType=Ref(param_instance_type), KeyName=Ref(param_keyname), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=str(True), DeleteOnTermination=str(True), Description='Network interface for web server', DeviceIndex=str(0), GroupSet=[Ref(param_vpc_security_group)], SubnetId=Ref(param_webserver_instance_subnet_id), ) ], Tags=Tags(Name=name_web_server, VPC=Ref(param_vpc_id)), UserData=Base64( Join('', [ '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n', 'yum update -y', '\n' '/opt/aws/bin/cfn-init --verbose ', ' --stack ', ref_stack_name, ' --resource %s ' % name_web_server, ' --region ', ref_region, '\n', '/opt/aws/bin/cfn-signal --exit-code $? ', ' --stack ', ref_stack_name, ' --resource ', name_web_server, '\n' ]))) template.add_resource(resource_web_server) template.add_output( Output('WebServer', Description='Web Server', Value=GetAtt(name_web_server, 'PublicIp'))) return template
) }), cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/home/ec2-user/script.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.amazonaws.com/scripts/script.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/usr/sbin/configure-storreduce-pat.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.amazonaws.com/scripts/configure-storreduce-pat.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), }), commands={ "init": { "command": Join("", [ "/home/ec2-user/script.sh && \
LaunchConfiguration( "LaunchConfiguration", Metadata=autoscaling.Metadata( cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/etc/rsyslog.d/20-somethin.conf": cloudformation.InitFile( source=Join( "", [ "http://", Ref(DeployBucket), ".s3.amazonaws.com/stacks/", Ref(RootStackName), "/env/etc/rsyslog.d/20-somethin.conf", ], ), mode="000644", owner="root", group="root", authentication="DeployUserAuth", ) }), services={ "sysvinit": cloudformation.InitServices({ "rsyslog": cloudformation.InitService( enabled=True,
def template(): t = Template() keyname_param = t.add_parameter( Parameter( "KeyName", Description= "Name of an existing EC2 KeyPair to enable SSH access to the instance", Type="String")) image_id_param = t.add_parameter( Parameter("ImageId", Description="ImageId of the EC2 instance", Type="String")) instance_type_param = t.add_parameter( Parameter("InstanceType", Description="Type of the EC2 instance", Type="String")) ScaleCapacity = t.add_parameter( Parameter( "ScaleCapacity", Default="1", Type="String", Description="Number of api servers to run", )) VPCAvailabilityZone2 = t.add_parameter( Parameter( "VPCAvailabilityZone2", MinLength="1", Type="String", Description="Second availability zone", MaxLength="255", )) VPCAvailabilityZone1 = t.add_parameter( Parameter( "VPCAvailabilityZone1", MinLength="1", Type="String", Description="First availability zone", MaxLength="255", )) SecurityGroup = t.add_parameter( Parameter( "SecurityGroup", Type="String", Description="Security group.", )) RootStackName = t.add_parameter( Parameter( "RootStackName", Type="String", Description="The root stack name", )) ApiSubnet2 = t.add_parameter( Parameter( "ApiSubnet2", Type="String", Description="Second private VPC subnet ID for the api app.", )) ApiSubnet1 = t.add_parameter( Parameter( "ApiSubnet1", Type="String", Description="First private VPC subnet ID for the api app.", )) ##################################################### # Launch Configuration ##################################################### LaunchConfig = t.add_resource( LaunchConfiguration( "LaunchConfiguration", Metadata=autoscaling.Metadata( cloudformation.Init( cloudformation.InitConfigSets(InstallAndRun=['Install']), Install=cloudformation.InitConfig( packages={ "apt": { "curl": [], "zip": [], "unzip": [], "git": [], "supervisor": [], "sqlite3": [], "nginx": [], "php7.2-fpm": [], "php7.2-cli": [], "php7.2-pgsql": [], "php7.2-sqlite3": [], "php7.2-gd": [], "php7.2-curl": [], "php7.2-memcached": [], "php7.2-imap": [], "php7.2-mysql": [], "php7.2-mbstring": [], "php7.2-xml": [], "php7.2-zip": [], "php7.2-bcmath": [], "php7.2-soap": [], "php7.2-intl": [], "php7.2-readline": [], "php-msgpack": [], "php-igbinary": [] } }, files=cloudformation.InitFiles({ "/etc/nginx/sites-available/default": cloudformation. InitFile(content=Join('', [ "server {\n", " listen 80 default_server;\n", " root /var/www/html/public;\n", " index index.html index.htm index.php;\n", " server_name _;\n", " charset utf-8;\n", " location = /favicon.ico { log_not_found off; access_log off; }\n", " location = /robots.txt { log_not_found off; access_log off; }\n", " location / {\n", " try_files $uri $uri/ /index.php$is_args$args;\n", " }\n", " location ~ \.php$ {\n", " include snippets/fastcgi-php.conf;\n", " fastcgi_pass unix:/run/php/php7.2-fpm.sock;\n", " }\n", " error_page 404 /index.php;\n", "}\n" ])), "/etc/supervisor/conf.d/supervisord.conf": cloudformation. InitFile(content=Join('', [ "[supervisord]\n", "nodaemon=true\n", "[program:nginx]\n", "command=nginx\n", "stdout_logfile=/dev/stdout\n", "stdout_logfile_maxbytes=0\n", "stderr_logfile=/dev/stderr\n", "stderr_logfile_maxbytes=0\n", "[program:php-fpm]\n", "command=php-fpm7.2\n", "stdout_logfile=/dev/stdout\n", "stdout_logfile_maxbytes=0\n", "stderr_logfile=/dev/stderr\n", "stderr_logfile_maxbytes=0\n", "[program:horizon]\n", "process_name=%(program_name)s\n", "command=php /var/www/html/artisan horizon\n", "autostart=true\n", "autorestart=true\n", "user=root\n", "redirect_stderr=true\n", "stdout_logfile=/var/www/html/storage/logs/horizon.log\n", ])), "/etc/php/7.2/fpm/php-fpm.conf": cloudformation.InitFile( content=Join('', [ "[global]\n", "pid = /run/php/php7.2-fpm.pid\n", "error_log = /proc/self/fd/2\n", "include=/etc/php/7.2/fpm/pool.d/*.conf\n" ])) }))), ), UserData=Base64( Join('', [ "#!/bin/bash -xe\n", "apt-get update -y\n", "apt-get install -y language-pack-en-base\n", "export LC_ALL=en_US.UTF-8\n", "export LANG=en_US.UTF-8\n", "apt-get install -y ruby\n", "wget https://aws-codedeploy-ap-south-1.s3.amazonaws.com/latest/install\n", "chmod +x ./install\n", "./install auto\n", "service codedeploy-agent start\n", "apt-get install -y software-properties-common python-software-properties\n", "add-apt-repository -y ppa:ondrej/php\n", "apt-get update -y\n", "apt-get install -y python-setuptools\n", "mkdir -p /opt/aws/bin\n", "wget https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n", "easy_install --script-dir /opt/aws/bin aws-cfn-bootstrap-latest.tar.gz\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", Ref("AWS::StackName"), " --resource LaunchConfiguration", " --configsets InstallAndRun ", " --region ", Ref("AWS::Region"), "\n" ])), ImageId=Ref("ImageId"), KeyName=Ref(keyname_param), BlockDeviceMappings=[ ec2.BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=ec2.EBSBlockDevice(VolumeSize="8")), ], InstanceType=Ref("InstanceType"), IamInstanceProfile="CodeDeployDemo-EC2-Instance-Profile", SecurityGroups=[Ref(SecurityGroup)])) ##################################################### # AutoScaling Groups ##################################################### AutoscalingGroup = t.add_resource( AutoScalingGroup( "AutoscalingGroup", DesiredCapacity=Ref(ScaleCapacity), Tags=[ Tag("App", "cc-worker", True), Tag("Name", "cc-worker", True) ], LaunchConfigurationName=Ref(LaunchConfig), MinSize=Ref(ScaleCapacity), MaxSize=Ref(ScaleCapacity), VPCZoneIdentifier=[Ref(ApiSubnet1), Ref(ApiSubnet2)], AvailabilityZones=[ Ref(VPCAvailabilityZone1), Ref(VPCAvailabilityZone2) ], HealthCheckType="EC2", UpdatePolicy=UpdatePolicy( AutoScalingReplacingUpdate=AutoScalingReplacingUpdate( WillReplace=True, ), AutoScalingRollingUpdate=AutoScalingRollingUpdate( PauseTime='PT5M', MinInstancesInService="1", MaxBatchSize='1', WaitOnResourceSignals=True)))) return t.to_json()
def generate_stack_template(): template = Template() generate_description(template) generate_version(template) # ---Parameters------------------------------------------------------------ param_vpc_id = Parameter( 'VpcIdentifer', Description= 'The identity of the VPC (vpc-abcdwxyz) in which this stack shall be created.', Type='AWS::EC2::VPC::Id', ) template.add_parameter(param_vpc_id) param_vpc_cidr_block = Parameter( 'VpcCidrBlock', Description= 'The CIDR block of the VPC (w.x.y.z/n) in which this stack shall be created.', Type='String', Default='10.0.0.0/16') template.add_parameter(param_vpc_cidr_block) param_database_instance_subnet_id = Parameter( 'VpcSubnetIdentifer', Description= 'The identity of the private subnet (subnet-abcdwxyz) in which the database server shall be created.', Type='AWS::EC2::Subnet::Id', ) template.add_parameter(param_database_instance_subnet_id) param_keyname = Parameter( 'PemKeyName', Description= 'Name of an existing EC2 KeyPair file (.pem) to use to create EC2 instances', Type='AWS::EC2::KeyPair::KeyName') template.add_parameter(param_keyname) param_instance_type = Parameter( 'EC2InstanceType', Description= 'EC2 instance type, reference this parameter to insure consistency', Type='String', Default= 't2.medium', # Prices from (2015-12-03) (Windows, us-west (North CA)) AllowedValues=[ # Source : https://aws.amazon.com/ec2/pricing/ 't2.small', # $0.044/hour 't2.micro', # $0.022/hour 't2.medium', # $0.088/hour 't2.large', # $0.166/hour 'm3.medium', # $0.140/hour 'm3.large', # $0.28/hour 'c4.large' # $0.221/hour ], ConstraintDescription='Must be a valid EC2 instance type') template.add_parameter(param_instance_type) param_s3_bucket = Parameter( 'S3Bucket', Description='The bucket in which applicable content can be found.', Type='String', Default='author-it-deployment-test-us-east-1') template.add_parameter(param_s3_bucket) param_s3_key = Parameter( 'S3Key', Description= 'The key within the bucket in which relevant files are located.', Type='String', Default='source/database/postgresql/single') template.add_parameter(param_s3_key) param_database_admin_password = Parameter( 'PostgresAdminPassword', Description='The password to be used by user postgres.', Type='String', NoEcho=True) template.add_parameter(param_database_admin_password) #---Mappings--------------------------------------------------------------- mapping_environment_attribute_map = template.add_mapping( 'EnvironmentAttributeMap', { 'ap-southeast-1': { 'DatabaseServerAmi': 'ami-1ddc0b7e' }, 'ap-southeast-2': { 'DatabaseServerAmi': 'ami-0c95b86f' }, 'us-east-1': { 'DatabaseServerAmi': 'ami-a4827dc9' }, 'us-west-1': { 'DatabaseServerAmi': 'ami-f5f41398' } }) # ---Resources------------------------------------------------------------- ref_stack_id = Ref('AWS::StackId') ref_region = Ref('AWS::Region') ref_stack_name = Ref('AWS::StackName') path_database_admin_script = 'usr/ec2-user/postgresql/set_admin_password.sql' name_database_server_wait_handle = 'DatabaseServerWaitHandle' cmd_postgresql_initdb = dict(command='service postgresql-95 initdb') cmd_start_postgresql_service = dict(command='service postgresql-95 start') cmd_set_postgres_user_password = dict(command='psql -U postgres -f %s' % path_database_admin_script) cmd_start_postgresql_on_startup = dict(command='chkconfig postgresql on') cmd_signal_success = dict(command='cfn-signal --exit-code $?') # Create an instance of AWS::IAM::Role for the instance. # This allows: # - Access to S3 bucket content. # - Stack updates resource_instance_role = template.add_resource( iam.Role('InstanceRole', AssumeRolePolicyDocument=Policy(Statement=[ Statement(Action=[AssumeRole], Effect=Allow, Principal=Principal('Service', ['ec2.amazonaws.com'])) ]), Path='/')) # Create the S3 policy and attach it to the role. template.add_resource( iam.PolicyType( 'InstanceS3DownloadPolicy', PolicyName='S3Download', PolicyDocument={ 'Statement': [{ 'Effect': 'Allow', 'Action': ['s3:GetObject'], 'Resource': Join('', ['arn:aws:s3:::', Ref(param_s3_bucket), '/*']) }, { 'Effect': 'Allow', 'Action': ['cloudformation:DescribeStacks', 'ec2:DescribeInstances'], 'Resource': '*' }] }, Roles=[Ref(resource_instance_role)])) # Create the CloudFormation stack update policy and attach it to the role. template.add_resource( iam.PolicyType('InstanceStackUpdatePolicy', PolicyName='StackUpdate', PolicyDocument={ 'Statement': [{ "Effect": "Allow", "Action": "Update:*", "Resource": "*" }] }, Roles=[Ref(resource_instance_role)])) # Create the AWS::IAM::InstanceProfile from the role for reference in the # database server instance definition. resource_instance_profile = template.add_resource( iam.InstanceProfile('InstanceProfile', Path='/', Roles=[Ref(resource_instance_role)])) # Create a security group for the postgresql instance. # This must be internal to the VPC only. name_security_group_database = 'VpcDatabaseSecurityGroup' resource_database_security_group = ec2.SecurityGroup( name_security_group_database, GroupDescription=Join( ' ', ['Security group for VPC database', Ref(param_vpc_id)]), Tags=Tags(Name=name_security_group_database), VpcId=Ref(param_vpc_id)) template.add_resource(resource_database_security_group) template.add_output( Output('SecurityGroupForDatabase', Description='Security group created for database in VPC.', Value=Ref(resource_database_security_group))) # Add ingress rule from VPC to database security group for database traffic. database_port = 5432 ssh_port = 22 template.add_resource( ec2.SecurityGroupIngress('DatabaseSecurityGroupDatabaseIngress', CidrIp=Ref(param_vpc_cidr_block), FromPort=str(database_port), GroupId=Ref(resource_database_security_group), IpProtocol='tcp', ToPort=str(database_port))) # Add ingress rule from VPC to database security group for ssh traffic. ssh_port = 22 template.add_resource( ec2.SecurityGroupIngress('DatabaseSecurityGroupSshIngress', CidrIp=Ref(param_vpc_cidr_block), FromPort=str(ssh_port), GroupId=Ref(resource_database_security_group), IpProtocol='tcp', ToPort=str(ssh_port))) # Create the metadata for the database instance. name_database_server = 'DatabaseServer' database_instance_metadata = cloudformation.Metadata( cloudformation.Init({ 'config': cloudformation.InitConfig( packages={ 'rpm': { 'postgresql': 'https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-6-x86_64/pgdg-ami201503-95-9.5-2.noarch.rpm' }, 'yum': { 'postgresql95': [], 'postgresql95-libs': [], 'postgresql95-server': [], 'postgresql95-devel': [], 'postgresql95-contrib': [], 'postgresql95-docs': [] } }, files=cloudformation.InitFiles({ # cfn-hup.conf initialization '/etc/cfn/cfn-hup.conf': cloudformation.InitFile(content=Join( '', [ '[main]\n', 'stack=', ref_stack_id, '\n', 'region=', ref_region, '\n', 'interval=2', '\n', 'verbose=true', '\n' ]), mode='000400', owner='root', group='root'), # cfn-auto-reloader.conf initialization '/etc/cfn/cfn-auto-reloader.conf': cloudformation.InitFile( content=Join( '', [ '[cfn-auto-reloader-hook]\n', 'triggers=post.update\n', 'path=Resources.%s.Metadata.AWS::CloudFormation::Init\n' % name_database_server, 'action=cfn-init.exe ', ' --verbose ' ' --stack ', ref_stack_name, ' --resource %s ' % name_database_server, # resource that defines the Metadata ' --region ', ref_region, '\n' ]), mode='000400', owner='root', group='root'), # # pg_hba.conf retrieval from S3 '/var/lib/pgsql9/data/pg_hba.conf': cloudformation.InitFile( source=Join( '/', [ # Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']), 'https://s3.amazonaws.com', Ref(param_s3_bucket), Ref(param_s3_key), 'conf' 'pg_hba.conf' ]), mode='000400', owner='root', group='root'), # postgresql.conf retrieval from S3 '/var/lib/pgsql9/data/postgresql.conf': cloudformation.InitFile( source=Join( '/', [ #Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']), 'https://s3.amazonaws.com', Ref(param_s3_bucket), Ref(param_s3_key), 'conf' 'postgresql.conf' ]), mode='000400', owner='root', group='root'), # pg_ident.conf retrieval from S3 '/var/lib/pgsql9/data/pg_ident.conf': cloudformation.InitFile( source=Join( '/', [ #Join('', ['https://s3-', ref_region, '.', 'amazonaws.com']), 'https://s3.amazonaws.com', Ref(param_s3_bucket), Ref(param_s3_key), 'conf' 'pg_ident.conf' ]), mode='000400', owner='root', group='root'), # script to set postgresql admin password. # (admin user = '******') path_database_admin_script: cloudformation.InitFile( source=Join('', [ 'ALTER USER postgres WITH PASSWORD ', Ref(param_database_admin_password), ';', '\n' ])) }), commands={ '10-postgresql_initdb': cmd_postgresql_initdb, '20-start_postgresql_service': cmd_start_postgresql_service, '30-set-postgres-user-password': cmd_set_postgres_user_password, '40-start-postgresql-on-startup': cmd_start_postgresql_on_startup, #'99-signal-success': cmd_signal_success }, services=dict(sysvinit=cloudformation.InitServices({ # start cfn-hup service - # required for CloudFormation stack update 'cfn-hup': cloudformation.InitService( enabled=True, ensureRunning=True, files=[ '/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/cfn-auto-reloader.conf' ]), # start postgresql service 'postgresql-9.5': cloudformation.InitService(enabled=True, ensureRunning=True), # Disable sendmail service - not required. 'sendmail': cloudformation.InitService(enabled=False, ensureRunning=False) }))) }), cloudformation.Authentication({ 'S3AccessCredentials': cloudformation.AuthenticationBlock( buckets=[Ref(param_s3_bucket)], roleName=Ref(resource_instance_role), type='S3') })) # Add a wait handle to receive the completion signal. #resource_database_server_wait_handle = template.add_resource( # cloudformation.WaitConditionHandle( # name_database_server_wait_handle # ) # ) #template.add_resource( # cloudformation.WaitCondition( # 'DatabaseServerWaitCondition', # DependsOn=name_database_server, # Handle=Ref(resource_database_server_wait_handle), # Timeout=300, # ) #) resource_database_server = ec2.Instance( name_database_server, DependsOn=name_security_group_database, IamInstanceProfile=Ref(resource_instance_profile), Metadata=database_instance_metadata, ImageId=FindInMap('EnvironmentAttributeMap', ref_region, 'DatabaseServerAmi'), InstanceType=Ref(param_instance_type), KeyName=Ref(param_keyname), SecurityGroupIds=[Ref(resource_database_security_group)], SubnetId=Ref(param_database_instance_subnet_id), Tags=Tags(Name=name_database_server, VPC=Ref(param_vpc_id)), UserData=Base64( Join('', [ '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n', '/opt/aws/bin/cfn-init --verbose ', ' --stack ', ref_stack_name, ' --resource DatabaseServer ', ' --region ', ref_region, '\n', '/opt/aws/bin/cfn-signal --exit-code $? ', ' --stack ', ref_stack_name, ' --resource ', name_database_server, '\n' ]))) template.add_resource(resource_database_server) template.add_output( Output('DatabaseServer', Description='PostgreSQL single instance database server', Value=Ref(resource_database_server))) return template
def generate_new_instance(counter): # Create base StorReduce instance instance = ec2.Instance(BASE_NAME + str(counter)) instance.DependsOn = [ elasticLB.title, SrrBucket.title, StorReduceHostProfile.title, AllInternalAccessSecurityGroup.title ] instance.ImageId = FindInMap("AWSAMIRegion", Ref("AWS::Region"), "AMI") instance.IamInstanceProfile = Ref(StorReduceHostProfile) # instance.AvailabilityZone = Select("0", Ref(AvailabilityZonesParam)) instance.InstanceType = Ref(InstanceTypeParam) instance.KeyName = Ref(KeyPairNameParam) #instance.SecurityGroupIds = Ref(SecurityGroupIdsParam) instance.SecurityGroupIds = [Ref(AllInternalAccessSecurityGroup)] instance.SubnetId = Select("0", Ref(PrivateSubnetsToSpanParam)) instance.UserData = Base64( Join("", [ """ #!/bin/bash -xe /opt/aws/bin/cfn-init -v --stack """, Ref("AWS::StackName"), " --resource " + instance.title + " --region ", Ref("AWS::Region"), "\n", "/opt/aws/bin/cfn-signal -e $? --stack ", Ref("AWS::StackName"), " --resource " + instance.title + " --region ", Ref("AWS::Region") ])) instance.Metadata = cloudformation.Metadata( cloudformation.Authentication({ "S3AccessCreds": cloudformation.AuthenticationBlock( type="S3", roleName=Ref(StorReduceHostRole), #Ref(HostRoleParam), buckets=[Ref(QSS3BucketNameParam)]) }), cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/home/ec2-user/init-srr.sh": cloudformation.InitFile(source=Sub( "https://${" + QSS3BucketNameParam.title + "}.${QSS3Region}.amazonaws.com/${" + QSS3KeyPrefixParam.title + "}scripts/init-srr.sh", **{ "QSS3Region": If("GovCloudCondition", "s3-us-gov-west-1", "s3") }), mode="000550", owner="root", group="root") }), commands={ "init-srr": { "command": Join("", [ "/home/ec2-user/init-srr.sh \"", Ref(BucketNameParam), "\" \'", Ref(StorReduceLicenseParam), "\' ", "\'", Ref(StorReducePasswordParam), "\' ", "\'", Ref(ShardsNumParam), "\' ", "\'", Ref(ReplicaShardsNumParam), "\' ", "\"", Ref(StorReduceHostNameParam), "\" ", "\"", GetAtt(elasticLB, "DNSName"), "\" ", "\"", Ref(elasticLB), "\" ", "\"", Ref("AWS::Region"), "\" ", "\"", GetAtt("Eth0", "PrimaryPrivateIpAddress"), "\" ", "\"", Ref(NumSRRHostsParam), "\"" ]) } }) })) instance.Tags = [{"Key": "Name", "Value": "StorReduce-QS-Base-Host"}] instance.CreationPolicy = CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')) return instance
"S3AccessCreds": cloudformation.AuthenticationBlock( type="S3", roleName=Ref(StorReduceHostRole), #Ref(HostRoleParam), buckets=[Ref(QSS3BucketNameParam)]) }), cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "/home/ec2-user/monitor-srr.sh": cloudformation.InitFile(source=Sub( "https://${" + QSS3BucketNameParam.title + "}.${QSS3Region}.amazonaws.com/${" + QSS3KeyPrefixParam.title + "}scripts/monitor-srr.sh", **{ "QSS3Region": If("GovCloudCondition", "s3-us-gov-west-1", "s3") }), mode="000550", owner="root", group="root"), }), commands={ "monitor-srr": { "command": Join("", [ "/home/ec2-user/monitor-srr.sh \"", GetAtt(base_instance, "PrivateDnsName"), "\" \'", Ref(StorReducePasswordParam), "\'" ]) }
files=cloudformation.InitFiles({ "/home/ec2-user/init-cron.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/init-cron.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/configure-s3-nat.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/configure-s3-nat.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/metrics.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/metrics.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/nat-globals.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/nat-globals.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/nat-lib.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/nat-lib.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/s3-nat-watchdog.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/s3-nat-watchdog.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), "/home/ec2-user/test-s3-nat.sh": cloudformation.InitFile( source=Join('', [ "http://", Ref(DeployBucket), ".s3.", Ref("AWS::Region"), ".amazonaws.com/scripts/test-s3-nat.sh" ]), mode="000550", owner="root", group="root", authentication="DeployUserAuth"), }),
Metadata=Metadata( cf.Init({ "configsets": cf.InitConfigSets(InstallandRun=["install", "config"]), "install": cf.InitConfig(packages={"yum": { "git": [], "wget": [] }}), "config": cf.InitConfig(files=cf.InitFiles({ "/tmp/example.txt": cf.InitFile(content=Join('', [ "This is a file example.\n", "See another examples in:\n", "https://github.com/rabeloo/cf-templates\n" ]), owner="root", group="root", mode="000600") }), ), })))) autoscaling_group_resource = t.add_resource( AutoScalingGroup("myAutoScalingGroup", DesiredCapacity=Ref(desInstances_param), MinSize=Ref(minInstances_param), MaxSize=Ref(maxInstances_param), Cooldown="300", LoadBalancerNames=FindInMap("RegionMap", {"Ref": "AWS::Region"},
# Define our launch configuration (AWS compatibility resource) launch_config = template.add_resource(autoscaling.LaunchConfiguration( "MyLaunchConfig", KeyName="bootstrap", InstanceType="t1.micro", ImageId="Ubuntu", SecurityGroups=[Ref(security_group)], Metadata=cloudformation.Init({ "config": cloudformation.InitConfig( files=cloudformation.InitFiles({ "file1": cloudformation.InitFile( content=Join('\n', [ "This is a", "test file" ]), mode="000755", owner="root", group="root", context=cloudformation.InitFileContext({ "security_group_id": Ref(security_group) }) ) }) ) }), UserData=Base64(Join('\n', [ "#!/bin/bash", "echo \"Upgrade started at $(date)\"", "apt-get update", "apt-get -y upgrade", "echo \"Upgrade complete at $(date)\"", ]))
}}, files=cfn.InitFiles({ '/etc/cfn/cfn-hup.conf': cfn.InitFile(content=Join('', [ '[main]\n', 'stack=', Ref('AWS::StackName'), '\n', 'region=', Ref('AWS::Region'), '\n', ]), mode='000400', owner='root', group='root'), '/etc/cfn/hooks.d/cfn-auto-reloader.conf': cfn.InitFile(content=Join('', [ '[cfn-auto-reloader-hook]\n', 'triggers=post.update\n', 'path=Resources.NatInstance.Metadata.AWS::CloudFormation::Init\n', 'action=/opt/aws/bin/cfn-init -v ', ' --stack=', Ref('AWS::StackName'), ' --resource=NatInstance', ' --region=', Ref('AWS::Region'), '\n', 'runas=root\n', ])) }), services={
files=cloudformation.InitFiles({ "/etc/cfn/cfn-hup.conf": cloudformation.InitFile( content=Join("", [ "[main]\n", "template=", Ref(AWS_STACK_ID), "\n", "region=", Ref(AWS_REGION), "\n", ]), mode="000400", owner="root", group="root", ), "/etc/cfn/hooks.d/cfn-auto-reload.conf": cloudformation.InitFile( content=Join("", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.%s." % container_instance_configuration_name, "Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -v ", " --stack", Ref(AWS_STACK_NAME), " --resource %s" % container_instance_configuration_name, " --region ", Ref("AWS::Region"), "\n", "runas=root\n", ])) }),
cfn.InitConfig(files=cfn.InitFiles({ "/etc/profile.d/cellos.sh": cfn.InitFile( content=make_content("""\ #!/bin/bash export cell_backend="aws" export cell_name="{{cell_name}}" export full_cell_name="cell-os--{{cell_name}}" export zk_elb="{{zk_elb}}" export zk_base_url="{{zk_base_url}}" export zk_cluster_list="{{zk_base_url}}/cluster/list" export marathon_elb="{{marathon_elb}}" export mesos_elb="{{mesos_elb}}" export gateway_elb="{{gateway_elb}}" export internal_gateway_elb="{{internal_gateway_elb}}" export SAASBASE_ACCESS_KEY_ID="{{saasbase_access_key_id}}" export SAASBASE_SECRET_ACCESS_KEY="{{saasbase_secret_access_key}}" export repository="{{repository}}" export cellos_version="{{cellos_version}}" export cell_bucket_name="{{cell_bucket_name}}" export cell_role="{{cell_role}}" export cell_modules="{{cell_modules}}" export machine_tags="{{machine_tags}}" export instance_id=`wget -qO- http://169.254.169.254/latest/meta-data/instance-id` export aws_stack_name="{{aws_stack_name}}" export aws_parent_stack_name="{{aws_parent_stack_name}}" export aws_region="{{aws_region}}" export aws_access_key_id="{{aws_access_key_id}}" export aws_secret_access_key="{{aws_secret_access_key}}" export aws_wait_handle="{{aws_wait_handle}}" """), owner="root", group="root", mode="000755", context=cfn.InitFileContext({ "zk_base_url": Join("", ["http://", Ref("ZookeeperElb"), "/exhibitor/v1"]), "zk_elb": Ref("ZookeeperElb"), "marathon_elb": Ref("MarathonElb"), "mesos_elb": Ref("MesosElb"), "gateway_elb": Ref("GatewayElb"), "internal_gateway_elb": Ref("InternalGatewayElb"), "aws_stack_name": Ref("AWS::StackName"), "aws_parent_stack_name": Ref("ParentStackName"), "aws_region": Ref("AWS::Region"), "saasbase_access_key_id": Ref("SaasBaseAccessKeyId"), "saasbase_secret_access_key": Ref("SaasBaseSecretAccessKey"), "repository": Ref("Repository"), "cellos_version": Ref("CellOsVersionBundle"), "cell_bucket_name": Ref("BucketName"), "cell_name": Ref("CellName"), "cell_role": Ref("Role"), "cell_modules": Ref("CellModules"), "machine_tags": Ref("Tags"), "aws_wait_handle": Ref("WaitHandle"), })), }))