def add_resources(self): metadata = { "AWS::CloudFormation::Init": { "configSets": { "wordpress_install": [ "install_wordpress"] }, "install_wordpress": { "packages": { "apt": { "apache2": [], "php": [], "php-mysql": [], "php7.0": [], "php7.0-mysql": [], "libapache2-mod-php7.0": [], "php7.0-cli": [], "php7.0-cgi": [], "php7.0-gd": [], "mysql-client": [], "sendmail": [] } }, "sources": { "/var/www/html": "http://wordpress.org/latest.tar.gz" }, "files": { "/tmp/create-wp-config": { "content": { "Fn::Join": ["", [ "#!/bin/bash\n", "cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php\n", "sed -i \"s/'database_name_here'/'", Ref( self.DBName), "'/g\" wp-config.php\n", "sed -i \"s/'username_here'/'", Ref( self.DBUser), "'/g\" wp-config.php\n", "sed -i \"s/'password_here'/'", Ref( self.DBPass), "'/g\" wp-config.php\n", "sed -i \"s/'localhost'/'", Ref( self.RDSEndpoint), "'/g\" wp-config.php\n" ]] }, "mode": "000500", "owner": "root", "group": "root" } }, "commands": { "01_configure_wordpress": { "command": "/tmp/create-wp-config", "cwd": "/var/www/html/wordpress" } } } } } self.WaitHandle = self.template.add_resource(cloudformation.WaitConditionHandle( "WaitHandle", )) self.WaitCondition = self.template.add_resource(cloudformation.WaitCondition( "WaitCondition", Handle=Ref(self.WaitHandle), Timeout="600", DependsOn="WebServerAutoScalingGroup", )) self.WebServerLaunchConfiguration = self.template.add_resource(autoscaling.LaunchConfiguration( "WebServerLaunchConfiguration", Metadata=metadata, UserData=Base64(Join("", [ "#!/bin/bash -x\n", "apt-get update\n", "apt-get install python-pip nfs-common -y \n", "mkdir -p /var/www/html/\n", "EC2_AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)\n", "echo \"$EC2_AZ.", Ref(self.FileSystemID), ".efs.", Ref( "AWS::Region"), ".amazonaws.com:/ /var/www/html/ nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0\" >> /etc/fstab\n" "mount -a\n", "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n", # "exec > /tmp/userdata.log 2>&1\n", "/usr/local/bin/cfn-init -v --stack ", Ref("AWS::StackName"), " --resource WebServerLaunchConfiguration ", " --configsets wordpress_install ", " --region ", Ref("AWS::Region"), "\n", "/bin/mv /var/www/html/wordpress/* /var/www/html/\n", "/bin/rm -f /var/www/html/index.html\n", "/bin/rm -rf /var/www/html/wordpress/\n", "chown www-data:www-data /var/www/html/* -R\n", "/usr/sbin/service apache2 restart\n", "/usr/bin/curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar\n", "/bin/chmod +x wp-cli.phar\n", "/bin/mv wp-cli.phar /usr/local/bin/wp\n", "cd /var/www/html/\n", "if ! $(sudo -u www-data /usr/local/bin/wp core is-installed); then\n", "sudo -u www-data /usr/local/bin/wp core install ", "--url='", Ref(self.Hostname), ".", Ref(self.Domain), "' ", "--title='Cloudreach Meetup - ", Ref( self.Environment), "' ", "--admin_user='******' ", "--admin_password='******' ", "--admin_email='*****@*****.**'\n", "wget https://s3-eu-west-1.amazonaws.com/sceptre-meetup-munich/header.jpg -O /var/www/html/wp-content/themes/twentyseventeen/assets/images/header.jpg\n", "chown www-data:www-data /var/www/html/wp-content/themes/twentyseventeen/assets/images/header.jpg\n", "fi\n", "/usr/local/bin/cfn-signal -e $? --stack ", Ref( "AWS::StackName"), " -r \"Webserver setup complete\" '", Ref(self.WaitHandle), "'\n" ] )), ImageId=FindInMap("AWSRegion2AMI", Ref("AWS::Region"), "AMI"), KeyName=Ref(self.KeyName), SecurityGroups=[Ref(self.WebSecurityGroup)], InstanceType=Ref(self.InstanceType), AssociatePublicIpAddress=True, )) self.WebServerAutoScalingGroup = self.template.add_resource(autoscaling.AutoScalingGroup( "WebServerAutoScalingGroup", MinSize=Ref(self.WebServerCapacity), DesiredCapacity=Ref(self.WebServerCapacity), MaxSize=Ref(self.WebServerCapacity), VPCZoneIdentifier=[Ref(self.Subnet1), Ref(self.Subnet2)], AvailabilityZones=[Ref(self.AvailabilityZone1), Ref(self.AvailabilityZone2)], Tags=autoscaling.Tags( Name=Join("-", [Ref(self.Project), "web", "asg"]), Environment=Ref(self.Environment), Project=Ref(self.Project), ), LoadBalancerNames=[Ref(self.ElasticLoadBalancer)], LaunchConfigurationName=Ref(self.WebServerLaunchConfiguration), )) self.WebServerScaleUpPolicy = self.template.add_resource(autoscaling.ScalingPolicy( "WebServerScaleUpPolicy", ScalingAdjustment="1", Cooldown="60", AutoScalingGroupName=Ref(self.WebServerAutoScalingGroup), AdjustmentType="ChangeInCapacity", )) self.WebServerScaleDownPolicy = self.template.add_resource(autoscaling.ScalingPolicy( "WebServerScaleDownPolicy", ScalingAdjustment="-1", Cooldown="60", AutoScalingGroupName=Ref(self.WebServerAutoScalingGroup), AdjustmentType="ChangeInCapacity", )) self.CPUAlarmLow = self.template.add_resource(cloudwatch.Alarm( "CPUAlarmLow", EvaluationPeriods="2", Dimensions=[ cloudwatch.MetricDimension( Name="AutoScalingGroupName", Value=Ref(self.WebServerAutoScalingGroup) ), ], AlarmActions=[Ref(self.WebServerScaleDownPolicy)], AlarmDescription="Scale-down if CPU < 70% for 1 minute", Namespace="AWS/EC2", Period="60", ComparisonOperator="LessThanThreshold", Statistic="Average", Threshold="70", MetricName="CPUUtilization", )) self.CPUAlarmHigh = self.template.add_resource(cloudwatch.Alarm( "CPUAlarmHigh", EvaluationPeriods="2", Dimensions=[ cloudwatch.MetricDimension( Name="AutoScalingGroupName", Value=Ref("WebServerAutoScalingGroup") ), ], AlarmActions=[Ref(self.WebServerScaleUpPolicy)], AlarmDescription="Scale-up if CPU > 50% for 1 minute", Namespace="AWS/EC2", Period="60", ComparisonOperator="GreaterThanThreshold", Statistic="Average", Threshold="50", MetricName="CPUUtilization", ))
ImageId=parameters.r_processing_ami, InstanceType='m4.large', UserData=base64.b64encode('#cloud-config\n' + yaml.safe_dump(r_server_user_data)), KeyName='bvanzant', SecurityGroups=[ parameters.database_client_sg, GetAtt(default_instance_sg, 'GroupId'), ] )) r_script_runner_asg = stack.add_resource(autoscaling.AutoScalingGroup( 'RScriptRunnerASG', LaunchConfigurationName=Ref(r_script_runner_lc), MaxSize=2, MinSize=1, Tags=autoscaling.Tags(Name='RScriptRunner'), VPCZoneIdentifier=parameters.private_subnets.values(), )) ourelb = stack.add_resource(elb.LoadBalancer( "ApplicationElasticLB", Name="ApplicationElasticLB", Scheme="internet-facing", Subnets=parameters.public_subnets.values(), SecurityGroups=[GetAtt(elb_sg, 'GroupId')], )) webserver_target_group = stack.add_resource(elb.TargetGroup( "WebserverTarget", Port=80,
# ImageId="ami-bc8ad2cb", # eu-west-1 KeyName=Ref(KeyName), SecurityGroups=[Ref(WebServerSecurityGroup)], InstanceType=Ref(InstanceType), AssociatePublicIpAddress=True, )) WebServerAutoScalingGroup = t.add_resource( autoscaling.AutoScalingGroup( "WebServerAutoScalingGroup", MinSize=Ref(WebServerCapacity), MaxSize="5", VPCZoneIdentifier=[Ref(PubSubnet1), Ref(PubSubnet2)], AvailabilityZones=[Ref(AvailabilityZone1), Ref(AvailabilityZone2)], Tags=autoscaling.Tags(Name=Join("-", ["WEB-ASG", Ref(Project)]), ), LoadBalancerNames=[Ref("ElasticLoadBalancer")], LaunchConfigurationName=Ref("WebServerLaunchConfiguration"), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal(Count=1, Timeout='PT10M')), UpdatePolicy=UpdatePolicy( AutoScalingRollingUpdate=AutoScalingRollingUpdate( PauseTime='PT5M', MinInstancesInService="1", MaxBatchSize='1', WaitOnResourceSignals=True)))) WebServerScaleUpPolicy = t.add_resource( autoscaling.ScalingPolicy( "WebServerScaleUpPolicy", ScalingAdjustment="1",
def AS_LaunchTemplate(): cfg.use_cfn_init = True InitConfigSets = ASInitConfigSets() CfmInitArgs = {} IBoxEnvApp = [] Tags_List = [] UserDataApp = [] for n in cfg.Apps: name = f"Apps{n}" # Ex. Apps1 envname = f"EnvApp{n}Version" # Ex EnvApp1Version reponame = f"{name}RepoName" # Ex Apps1RepoName UserDataApp.extend(["#${%s}\n" % envname]) p_EnvAppVersion = Parameter( envname, Description=f"Application {n} version", AllowedPattern="^[a-zA-Z0-9-_.]*$", ) p_AppsRepoName = Parameter( reponame, Description=f"App {n} Repo Name - empty for default based on env/role", AllowedPattern="^[a-zA-Z0-9-_.]*$", ) # parameters add_obj( [ p_EnvAppVersion, p_AppsRepoName, ] ) # conditions add_obj( { name: And( Not(Equals(Ref(envname), "")), Not(get_condition("", "equals", "None", reponame)), ) } ) InitConfigApps = ASInitConfigApps(name) CfmInitArgs[name] = InitConfigApps InitConfigAppsBuilAmi = ASInitConfigAppsBuildAmi(name) # AUTOSPOT - Let cfn-init always prepare instances on boot # CfmInitArgs[name + 'BuildAmi'] = InitConfigAppsBuilAmi CfmInitArgs[name] = InitConfigAppsBuilAmi IBoxEnvApp.extend( [ f"export EnvApp{n}Version=", Ref(envname), "\n", f"export EnvRepo{n}Name=", get_endvalue(reponame), "\n", ] ) InitConfigSetsApp = If(name, name, Ref("AWS::NoValue")) InitConfigSetsAppBuilAmi = If(name, f"{name}BuildAmi", Ref("AWS::NoValue")) IndexSERVICES = InitConfigSets.data["default"].index("SERVICES") InitConfigSets.data["default"].insert(IndexSERVICES, InitConfigSetsApp) # AUTOSPOT - Let cfn-init always prepare instances on boot # InitConfigSets.data['buildamifull'].append( # InitConfigSetsAppBuilAmi) InitConfigSets.data["buildamifull"].append(InitConfigSetsApp) Tags_List.append(asg.Tag(envname, Ref(envname), True)) # outputs Output_app = Output(envname, Value=Ref(envname)) Output_repo = Output(reponame, Value=get_endvalue(reponame)) add_obj([Output_app, Output_repo]) InitConfigSetup = ASInitConfigSetup() InitConfigSetup.ibox_env_app = IBoxEnvApp InitConfigSetup.setup() InitConfigCodeDeploy = ASInitConfigCodeDeploy() CfmInitArgs["SETUP"] = InitConfigSetup CfmInitArgs["CWAGENT"] = ASInitConfigCloudWatchAgent("") if cfg.CodeDeploy: CfmInitArgs["CODEDEPLOY"] = InitConfigCodeDeploy if not getattr(cfg, "IBOX_LAUNCH_TEMPLATE_NO_WAIT_ELB_HEALTH", False): for lb in cfg.LoadBalancer: # LoadBalancerClassic if cfg.LoadBalancerType == "Classic": InitConfigELB = ASInitConfigELBClassic(scheme=lb) CfmInitArgs["ELBWAITER"] = InitConfigELB # LoadBalancerApplication if cfg.LoadBalancerType == "Application": InitConfigELB = ASInitConfigELBApplication(scheme=lb) CfmInitArgs["ELBWAITER"] = InitConfigELB # LoadBalancerNetwork if cfg.LoadBalancerType == "Network": for k in cfg.Listeners: InitConfigELB = ASInitConfigELBApplication( scheme=f"TargetGroupListeners{k}{lb}" ) CfmInitArgs["ELBWAITER"] = InitConfigELB if getattr(cfg, "IBOX_LAUNCH_TEMPLATE_NO_SG_EXTRA", False): SecurityGroups = [] else: SecurityGroups = cfg.SecurityGroupsImport # Resources R_LaunchTemplate = ec2.LaunchTemplate( "LaunchTemplate", LaunchTemplateName=Sub("${AWS::StackName}-${EnvRole}"), LaunchTemplateData=ASLaunchTemplateData( "LaunchTemplateData", UserDataApp=UserDataApp ), ) R_LaunchTemplate.LaunchTemplateData.NetworkInterfaces[0].Groups.extend( SecurityGroups ) # Import role specific cfn definition try: # Do not use role but direct cfg yaml configuration (ecs + cluster) cfn_envrole = f"cfn_{cfg.IBOX_ROLE_EX}" except Exception: cfn_envrole = f"cfn_{cfg.envrole}" cfn_envrole = cfn_envrole.replace("-", "_") if cfn_envrole in globals(): # Ex cfn_client_portal CfnRole = globals()[cfn_envrole]() CfmInitArgs.update(CfnRole) if cfg.use_cfn_init: R_LaunchTemplate.Metadata = cfm.Metadata( { "CloudFormationInitVersion": If( "CloudFormationInit", Ref("EnvStackVersion"), Ref("AWS::NoValue"), ) }, cfm.Init(InitConfigSets, **CfmInitArgs), cfm.Authentication( { "CfnS3Auth": cfm.AuthenticationBlock( type="S3", buckets=[ Sub(cfg.BucketNameAppRepository), Sub(cfg.BucketNameAppData), ], roleName=Ref("RoleInstance"), ) } ), ) add_obj(R_LaunchTemplate) Tags = asg.Tags() Tags.tags = Tags_List return Tags
def build_template(self): t = self._init_template() min_inst = t.add_parameter( Parameter('Input{}ASGMinInstances'.format(self.stack_name), Type='String', Default='2', Description='{} Minimum # of instances'.format( self.stack_name))) max_inst = t.add_parameter( Parameter('Input{}ASGMaxInstances'.format(self.stack_name), Type='String', Default='10', Description='{} Minimum # of instances'.format( self.stack_name))) des_inst = t.add_parameter( Parameter('Input{}ASGDesiredInstances'.format(self.stack_name), Type='String', Default='2', Description='{} Minimum # of instances'.format( self.stack_name))) inst_type = t.add_parameter( Parameter('Input{}ASGInstanceType'.format(self.stack_name), Type='String', Default='t2.micro', Description='{} Instance Type'.format(self.stack_name))) inst_tag_name = t.add_parameter( Parameter('Input{}ASGTagName'.format(self.stack_name), Type='String', Default='{}ASG'.format(self.name), Description='{} Instance Name Tag'.format( self.stack_name))) # termination policies term_policies = t.add_parameter( Parameter('Input{}ASGTerminationPolicies'.format(self.stack_name), Type='String', Default='Default', Description='{} Instance Type'.format(self.stack_name))) # root file size root_device_size = t.add_parameter( Parameter("Input{}ASGRootDeviceSize".format(self.stack_name), Type="String", Default="20", Description="{} Root Device File Size".format( self.stack_name))) # root device name root_device_name = t.add_parameter( Parameter("Input{}ASGRootDeviceName".format(self.stack_name), Type="String", Default="/dev/xvda", Description="{} Root Device Name".format( self.stack_name))) # root device type root_device_type = t.add_parameter( Parameter("Input{}ASGRootDeviceType".format(self.stack_name), Type="String", Default="gp2", Description="{} Root Device Type".format( self.stack_name))) # instance profile instance_profile_param = t.add_parameter( Parameter(self.iam_profile.output_instance_profile(), Type='String')) min_in_service = Ref(des_inst) # sec groups sec_groups = [ Ref( t.add_parameter( Parameter(sg.output_security_group(), Type='String'))) for sg in self.security_groups ] # user data params user_data = [] for i in range(0, 4): user_data.append( Ref( t.add_parameter( Parameter('{}UserData{}'.format(self.stack_name, i), Type='String', Default=' ', Description='{} UserData #{}'.format( self.stack_name, i))))) # subnet list if self.private_subnet: sn_list = [i for i in self.vpc_stack.output_private_subnets()] associate_public_ip = False else: sn_list = [i for i in self.vpc_stack.output_public_subnets()] associate_public_ip = True sn_list = [ Ref(t.add_parameter(Parameter(i, Type='String'))) for i in sn_list ] elb_list = [ Ref(t.add_parameter(Parameter(elb.output_elb(), Type='String'))) for elb in self.elb_stacks ] lconfig = t.add_resource( autoscaling.LaunchConfiguration( '{}LaunchConfiguration'.format(self.name), AssociatePublicIpAddress=associate_public_ip, IamInstanceProfile=Ref(instance_profile_param), BlockDeviceMappings=[ ec2.BlockDeviceMapping( DeviceName=Ref(root_device_name), Ebs=ec2.EBSBlockDevice( VolumeSize=Ref(root_device_size), VolumeType=Ref(root_device_type), DeleteOnTermination=True)) ], InstanceType=Ref(inst_type), SecurityGroups=sec_groups, ImageId=self.ami, UserData=Base64( Join( '', [ "#!/bin/bash\n", "exec > >(tee /var/log/user-data.log|logger ", "-t user-data -s 2>/dev/console) 2>&1\n", ] + user_data + [ "\n", "\n", "curl -L https://gist.github.com/ibejohn818", "/aa2bcd6743a59f62e1baa098d6365a61/raw", "/install-cfn-init.sh", " -o /tmp/install-cfn-init.sh && chmod +x /tmp/install-cfn-init.sh", # noqa "\n", "/tmp/install-cfn-init.sh ", " {}AutoScalingGroup".format(self.stack_name), " ", Ref("AWS::StackName"), " ", Ref("AWS::Region"), "\n", ])))) if self.keyname: lconfig.KeyName = self.keyname asg = t.add_resource( autoscaling.AutoScalingGroup( '{}AutoScalingGroup'.format(self.stack_name), LaunchConfigurationName=Ref(lconfig), MinSize=Ref(min_inst), MaxSize=Ref(max_inst), DesiredCapacity=Ref(des_inst), VPCZoneIdentifier=sn_list, HealthCheckType='EC2', TerminationPolicies=[Ref(term_policies)], LoadBalancerNames=elb_list, Tags=autoscaling.Tags(Name=Ref(inst_tag_name)), UpdatePolicy=UpdatePolicy( AutoScalingRollingUpdate=AutoScalingRollingUpdate( PauseTime=self.pause_time, MinInstancesInService=min_in_service, MaxBatchSize=str(self.update_policy_instance_count), WaitOnResourceSignals=True)))) t.add_output([Output('{}ASG'.format(self.stack_name), Value=Ref(asg))]) return t
Version=GetAtt('WordPressAsgLaunchTemplate', 'LatestVersionNumber')), Cooldown=360, MinSize=If( 'IsProd', '2', Ref('pAsgMinSize')), # Dev gets 1 but we need 2 for HA in Prod MaxSize=If('IsProd', Ref('pAsgMaxSize'), '1'), # Dev gets max=1 but max=5 for Prod. # AvailabilityZones=If('IsProd', [Ref('pVPCAvailabilityZone1'), Ref('pVPCAvailabilityZone2')], [Ref('pVPCAvailabilityZone1')]), HealthCheckType="EC2", MetricsCollection=[ autoscaling.MetricsCollection(Granularity='1Minute') ], VPCZoneIdentifier=[Ref('pSubnet1'), Ref('pSubnet2')], Tags=autoscaling.Tags(Name=Join( '_', ['WordPressASG', Ref('AWS::StackName')]), **base_tags))) # This is the RDS instance. We set MultiAZ to True here if we're in a Production Environment. rds = template.add_resource( rds.DBInstance( "WordPressRDS", DBName=Ref('pDBName'), AllocatedStorage=5, DBInstanceClass=Ref('pRDSInstance'), Engine="MySQL", EngineVersion="5.7", MasterUsername="******", MasterUserPassword="******", VPCSecurityGroups=[Ref('RDSSG')], #DBSubnetGroupName='default2', # Depending on your VPC this might be required
])) instance_profile = template.add_resource( iam.InstanceProfile("InstanceProfile", Path="/", Roles=[Ref(role)])) launch_configuration = template.add_resource( asc.LaunchConfiguration("LaunchConfiguration", ImageId=Ref(image), SecurityGroups=[Ref(security_group)], InstanceMonitoring=False, IamInstanceProfile=Ref(instance_profile), InstanceType=Ref(instance_type), KeyName=Ref(ssh_key_name), UserData=from_file("out/cloud-config.yaml"), AssociatePublicIpAddress=True)) autoscaling_group = template.add_resource( asc.AutoScalingGroup( "AutoScalingGroup", DependsOn=["PublicRoute"], AvailabilityZones=[Ref(availability_zone_1), Ref(availability_zone_2)], VPCZoneIdentifier=[Ref(subnet_1), Ref(subnet_2)], LaunchConfigurationName=Ref(launch_configuration), MinSize=0, MaxSize=1, DesiredCapacity=1, Tags=asc.Tags(Name="euca.me"))) print(template.to_json())
def main(): # Meta t.add_version("2010-09-09") t.add_description("Template for auto-scaling in an Application" "load balancer target group. " "The ALB will be used as an A Alias target " "for a specified Route53 hosted zone. " "This template also showcases " "Metadata Parameter Grouping, " "Special AWS Parameter Types, " "and Cloudformation Outputs with Exports" "which can be imported into other templates.") t.add_metadata({ "Author": "https://github.com/hmain/", "LastUpdated": "2017 01 31", "Version": "1", }) # Parameter grouping t.add_metadata({ "AWS::CloudFormation::Interface": { "ParameterGroups": [{ "Label": { "default": "Global parameters" }, "Parameters": ["environment"] }, { "Label": { "default": "Application Loadbalancer" }, "Parameters": [ "albSubnets", "loadbalancerPrefix", "loadBalancerArn", "albPaths", "albPort" ] }, { "Label": { "default": "VPC" }, "Parameters": ["ec2Subnets", "VPC", "securityGroup"] }, { "Label": { "default": "EC2" }, "Parameters": ["ec2Name", "ec2Type", "ec2Key"] }, { "Label": { "default": "Auto-scaling" }, "Parameters": [ "asgCapacity", "asgMinSize", "asgMaxSize", "asgCooldown", "asgHealthGrace" ] }, { "Label": { "default": "Route53" }, "Parameters": ["route53HostedZoneId", "route53HostedZoneName"] }] } }) AddAMI(t) environment = t.add_parameter( Parameter( "environment", Default="dev", Type="String", Description="Development or Production environment", AllowedValues=["dev", "prod"], ConstraintDescription="dev or prod", )) route53_hosted_zone_id = t.add_parameter( Parameter("route53HostedZoneId", Default="", Type="AWS::Route53::HostedZone::Id", Description="Route53 DNS zone ID")) route53_hosted_zone_name = t.add_parameter( Parameter("route53HostedZoneName", Default="my.aws.dns.com", Type="String", Description="Route53 hosted zone name")) security_group = t.add_parameter( Parameter("securityGroup", Default="", Type="List<AWS::EC2::SecurityGroup::Id>", Description="Which security groups to use")) alb_paths = t.add_parameter( Parameter( "albPaths", Default="/", Type="CommaDelimitedList", Description="Path-patterns you want the loadbalancer to point to in " "your application")) albPort = t.add_parameter( Parameter("albPort", Default="80", Type="Number", Description="Which loadbalancer port to use")) ec2_subnets = t.add_parameter( Parameter("ec2Subnets", Default="", Type="List<AWS::EC2::Subnet::Id>", Description="Private subnets for the instances.")) alb_subnets = t.add_parameter( Parameter("albSubnets", Default="", Type="List<AWS::EC2::Subnet::Id>", Description="Public subnets for the load balancer.")) loadbalancer_prefix = t.add_parameter( Parameter( "loadbalancerPrefix", Default="", Type="String", Description="Specify a prefix for your loadbalancer", )) vpc = t.add_parameter( Parameter("VPC", Default="", Type="AWS::EC2::VPC::Id", Description="Environment VPC")) # Auto scaling group parameters asg_capacity = t.add_parameter( Parameter("asgCapacity", Default="0", Type="Number", Description="Number of instances")) asg_min_size = t.add_parameter( Parameter("asgMinSize", Default="0", Type="Number", Description="Minimum size of AutoScalingGroup")) asg_max_size = t.add_parameter( Parameter("asgMaxSize", Default="1", Type="Number", Description="Maximum size of AutoScalingGroup")) asg_cooldown = t.add_parameter( Parameter( "asgCooldown", Default="300", Type="Number", Description="Cooldown before starting/stopping another instance")) asg_health_grace = t.add_parameter( Parameter( "asgHealthGrace", Default="300", Type="Number", Description="Wait before starting/stopping another instance")) # EC2 parameters ec2_name = t.add_parameter( Parameter("ec2Name", Default="myApplication", Type="String", Description="Name of the instances")) ec2_type = t.add_parameter( Parameter("ec2Type", Default="t2.large", Type="String", Description="Instance type.")) ec2_key = t.add_parameter( Parameter("ec2Key", Default="", Type="AWS::EC2::KeyPair::KeyName", Description="EC2 Key Pair")) # Launchconfiguration ec2_launchconfiguration = t.add_resource( autoscaling.LaunchConfiguration( "EC2LaunchConfiguration", ImageId=FindInMap("windowsAMI", Ref("AWS::Region"), "AMI"), KeyName=Ref(ec2_key), SecurityGroups=Ref(security_group), InstanceType=Ref(ec2_type), AssociatePublicIpAddress=False, )) # Application ELB alb_target_group = t.add_resource( elb.TargetGroup("albTargetGroup", HealthCheckPath=Select("0", Ref(alb_paths)), HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher(HttpCode="200"), Name=Ref(ec2_name), Port=80, Protocol="HTTP", UnhealthyThresholdCount="3", VpcId=Ref(vpc))) # Auto scaling group t.add_resource( autoscaling.AutoScalingGroup( "autoScalingGroup", DesiredCapacity=Ref(asg_capacity), Tags=autoscaling.Tags(Environment=Ref(environment)), VPCZoneIdentifier=Ref(ec2_subnets), TargetGroupARNs=[Ref(alb_target_group)], MinSize=Ref(asg_min_size), MaxSize=Ref(asg_max_size), Cooldown=Ref(asg_cooldown), LaunchConfigurationName=Ref(ec2_launchconfiguration), HealthCheckGracePeriod=Ref(asg_health_grace), HealthCheckType="EC2", )) # Application Load Balancer application_load_balancer = t.add_resource( elb.LoadBalancer("applicationLoadBalancer", Name=Ref(loadbalancer_prefix), Scheme="internet-facing", Subnets=Ref(alb_subnets), SecurityGroups=Ref(security_group))) alb_listener = t.add_resource( elb.Listener("albListener", Port=Ref(albPort), Protocol="HTTP", LoadBalancerArn=Ref(application_load_balancer), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(alb_target_group)) ])) t.add_resource( elb.ListenerRule("albListenerRule", ListenerArn=Ref(alb_listener), Conditions=[ elb.Condition(Field="path-pattern", Values=Ref(alb_paths)) ], Actions=[ elb.Action(Type="forward", TargetGroupArn=Ref(alb_target_group)) ], Priority="1")) # Route53 t.add_resource( route53.RecordSetGroup( "route53RoundRobin", HostedZoneId=Ref(route53_hosted_zone_id), RecordSets=[ route53.RecordSet( Weight=1, SetIdentifier=Join(".", [ Ref(environment), Ref(route53_hosted_zone_name), "ELB" ]), Name=Join( ".", [Ref(environment), Ref(route53_hosted_zone_name)]), Type="A", AliasTarget=route53.AliasTarget( GetAtt(application_load_balancer, "CanonicalHostedZoneID"), GetAtt(application_load_balancer, "DNSName"))) ])) t.add_output( Output( "URL", Description="URL of the website", Value=Join("", [ "http://", GetAtt(application_load_balancer, "DNSName"), Select("0", Ref(alb_paths)) ]), Export=Export(Sub("${AWS::StackName}-URL")), )) print(t.to_json())
"SaasBaseSecretAccessKey", Type="String", Description= "SaasBase S3 repo read-only AWS account Secret Access Key (http://saasbase.corp.adobe.com/ops/operations/deployment.html)", )) t.add_condition("HasIamInstanceProfile", Not(Equals(Ref(iam_instance_profile), ""))) t.add_condition("HasLbs", Not(Equals(Join("", Ref(load_balancer_names)), ""))) body = t.add_resource( asn.AutoScalingGroup( "Body", DesiredCapacity=Ref(group_size), Tags=asn.Tags( role=Ref(role), cell=Ref(cell_name), ), LaunchConfigurationName=Ref("BodyLaunchConfig"), MinSize="0", MaxSize="1000", VPCZoneIdentifier=[Ref(subnet)], LoadBalancerNames=If("HasLbs", Ref(load_balancer_names), []), TerminationPolicies=["NewestInstance", "ClosestToNextInstanceHour"])) ROOT_DEVICE_SIZE = 200 root_block_device_mapping = [ ec2.BlockDeviceMapping(DeviceName='/dev/sda1', Ebs=ec2.EBSBlockDevice(DeleteOnTermination=True, VolumeType='gp2', VolumeSize=ROOT_DEVICE_SIZE)) ]