def create_loadbalancer(): return [ elb.LoadBalancer( 'tlsFrontend', SecurityGroups=[Ref('secgrpLoadBalancer')], Subnets=[Ref('subnetA'), Ref('subnetB')], Tags=_tags(), ), elb.Listener( 'tlsFrontendListener', Certificates=[ elb.Certificate(CertificateArn=Ref('certificateArn')), ], DefaultActions=[ elb.Action(TargetGroupArn=Ref('tlsFrontendApplication'), Type='forward'), ], LoadBalancerArn=Ref('tlsFrontend'), Port=443, Protocol='HTTPS', ), elb.ListenerRule( 'tlsFrontendJenkinsRule', Actions=[ elb.Action(TargetGroupArn=Ref('tlsFrontendJenkins'), Type='forward'), ], Conditions=[ elb.Condition(Field='host-header', Values=[_subdomain_for_jenkins()]), ], ListenerArn=Ref('tlsFrontendListener'), Priority=1, ), elb.TargetGroup( 'tlsFrontendApplication', HealthCheckIntervalSeconds=300, HealthCheckPath='/health', Port=80, Protocol='HTTP', Tags=_tags(), Targets=[ elb.TargetDescription(Id=Ref('devserver'), Port=80), ], VpcId=Ref('vpc'), ), elb.TargetGroup( 'tlsFrontendJenkins', HealthCheckIntervalSeconds=300, HealthCheckPath='/robots.txt', Port=8080, Protocol='HTTP', Tags=_tags(), Targets=[ elb.TargetDescription(Id=Ref('devserver'), Port=8080), ], VpcId=Ref('vpc'), ), ]
def create_load_balancers(self): t = self.template self.load_balancer = t.add_resource( alb.LoadBalancer( f"PrimaryAlb", SecurityGroups=[], ))
def add_alb(self, template, provision_refs, instances): alb = template.add_resource( elb.LoadBalancer( 'ALB', LoadBalancerAttributes=[ elb.LoadBalancerAttributes( Key='idle_timeout.timeout_seconds', Value='3600') ], Subnets=provision_refs.subnets, Type='application', Scheme='internet-facing', IpAddressType='ipv4', SecurityGroups=[provision_refs.security_group_alb])) default_target_group = template.add_resource( elb.TargetGroup( 'DefaultTargetGroup', Port=46658, Protocol='HTTP', Targets=[ elb.TargetDescription(Id=Ref(instance)) for instance in instances ], HealthCheckProtocol='HTTP', HealthCheckPath='/rpc', TargetGroupAttributes=[ elb.TargetGroupAttribute(Key='stickiness.enabled', Value='true'), elb.TargetGroupAttribute(Key='stickiness.type', Value='lb_cookie'), elb.TargetGroupAttribute( Key='stickiness.lb_cookie.duration_seconds', Value='86400'), ], VpcId=provision_refs.vpc)) template.add_resource( elb.Listener( 'ALBListener', DefaultActions=[ elb.Action('DefaultAction', Type='forward', TargetGroupArn=Ref(default_target_group)) ], LoadBalancerArn=Ref(alb), Port=46658, Protocol='HTTPS', SslPolicy='ELBSecurityPolicy-TLS-1-2-2017-01', Certificates=[ elb.Certificate( CertificateArn= 'arn:aws:acm:us-east-1:489745816517:certificate/' 'fbb68210-264e-4340-9c5c-a7687f993579') ])) provision_refs.alb = alb
def create_load_balancer_resource(template, load_balancer_security_group_resource, subnets_parameter): return template.add_resource( elb.LoadBalancer( 'LoadBalancer', Scheme='internet-facing', SecurityGroups=[ GetAtt(load_balancer_security_group_resource, 'GroupId')], Subnets=Ref(subnets_parameter), ) )
def create_elbv2(self, name, subnets, security_groups=[], lb_type="application", scheme="internet-facing", tags={}, lb_attributes=False): """ Creates an Amazon Load Balancer (ELBv2) - (software load balancer) not to be confused with an ELB :param name: Name for the ALB :param subnets: Subnets in which to create it (must be >1) :param security_groups: SGs to assign to the ALB :param lb_type: LB type (application, network) :param scheme: Scheme (internet-facing, internal) :param tags: any tags to assign to the LB :param lb_attributes: Additional attributes """ load_balancer = elbv2.LoadBalancer(name, Subnets=subnets, SecurityGroups=security_groups, Scheme=scheme, Type=lb_type, Tags=tags) if lb_attributes: attributes = [] for attr in lb_attributes: attributes.append( elbv2.LoadBalancerAttributes(Key=attr['key'], Value=attr['value'])) load_balancer.LoadBalancerAttributes = attributes self.template.add_resource(load_balancer) if lb_type == "application": lb_abbreviation = "ALB" elif lb_type == "network": lb_abbreviation = "NLB" self.template.add_output( Output( # Todo Sort out outputs, based on Type. name, Value=Ref(name), Description=lb_abbreviation + u" ARN", Export=Export(Sub("${AWS::StackName}-" + name)))) self.template.add_output( Output(name + "DNS", Value=GetAtt(name, "DNSName"), Description=lb_abbreviation + u" DNS Name.", Export=Export(Sub("${AWS::StackName}-" + name + "DNS"))))
def create_load_balancer_alb(self, template, sg_name): alb_name = ALB_NAME load_balancer = template.add_resource( alb.LoadBalancer(alb_name, Scheme="internal", Subnets=Ref("PrivateSubnets"), SecurityGroups=[Ref(sg_name)])) template.add_output( Output("CanonicalHostedZoneID", Value=load_balancer.GetAtt("CanonicalHostedZoneID"))) template.add_output( Output("DNSName", Value=load_balancer.GetAtt("DNSName")))
def gen_load_balancer(self): self.load_balancer = elasticloadbalancingv2.LoadBalancer( "LoadBalancer", SecurityGroups=[Ref(self.load_balancer_security_group)], Subnets=[ self.import_value("vpc", "PublicSubnet0"), self.import_value("vpc", "PublicSubnet1"), ], Scheme="internet-facing", ) self.template.add_resource(self.load_balancer) value = GetAtt(self.load_balancer, "DNSName") self.export_value(value, "DNSName")
def create_alb(stack, name, subnets=[], security_groups=[], condition_field='', scheme='internet-facing'): """Add Application Loadbalancer Resource.""" return stack.stack.add_resource( alb.LoadBalancer('{0}ALB'.format(name), Condition=condition_field, Name='{0}ALB'.format(name), Scheme=scheme, SecurityGroups=security_groups, Subnets=subnets))
def app_elb(template, name, subnets, instances, vpc, instance_port=443, load_balancer_port=443, instance_proto='HTTPS', load_balancer_proto='HTTPS', securitygroups=None): """Create an elastic load balancer """ applb = elbv2.LoadBalancer( name, template=template, Subnets=[Ref(r) for r in subnets], SecurityGroups=[Ref(r) for r in securitygroups], ) targetgroup = elbv2.TargetGroup( title=name + 'targetgroup', template=template, Port=instance_port, Protocol=instance_proto, VpcId=Ref(vpc), Targets=[elbv2.TargetDescription(Id=Ref(r)) for r in instances], HealthCheckIntervalSeconds=10, # HealthCheckPath="/", # HealthCheckPort="traffic-port", # HealthCheckProtocol="HTTP", # HealthCheckTimeoutSeconds=5, # UnhealthyThresholdCount=10, # HealthyThresholdCount=2, ) elbv2.Listener( title=(name + 'listener'), template=template, DefaultActions=[ elbv2.Action(TargetGroupArn=Ref(targetgroup), Type='forward') ], LoadBalancerArn=Ref(applb), Port=load_balancer_port, Protocol=load_balancer_proto, ) return applb
def add_resources_and_outputs(self): """Add resources to template.""" template = self.template variables = self.get_variables() v2lb = template.add_resource( elasticloadbalancingv2.LoadBalancer( 'V2LoadBalancer', Name=variables['LbName'].ref, Scheme=variables['Scheme'].ref, SecurityGroups=variables['SgIdList'].ref, Subnets=variables['Subnets'].ref, Tags=Tags(Application=variables['ApplicationName'].ref, Environment=variables['EnvironmentName'].ref, Name=variables['LbName'].ref), Type=variables['Type'].ref)) template.add_output( Output( 'LbDnsName', Description="DNS name of the load balancer", Value=GetAtt(v2lb, "DNSName"), )) template.add_output( Output( 'LbName', Description="Name of the load balancer", Value=GetAtt(v2lb, "LoadBalancerName"), )) template.add_output( Output( "LbArn", Description="ARN of the load balancer", Value=Ref(v2lb), ))
)) 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, Protocol='HTTP', VpcId=parameters.vpc_id, )) webserver_listener = stack.add_resource(elb.Listener( "WebserverListener", Port=80, Protocol='HTTP',
def create_template(self): self.vars = self.validate_user_data() t = self.template if self.vars["LogBucket"]: self.log_bucket = self.create_log_bucket() lb_attrubutes = [ elb.LoadBalancerAttributes(Key="access_logs.s3.enabled", Value="true"), elb.LoadBalancerAttributes(Key="access_logs.s3.bucket", Value=self.vars["LogBucket"]), elb.LoadBalancerAttributes(Key="access_logs.s3.prefix", Value=self.vars["LogPrefix"]), ] else: self.log_bucket = NoValue lb_attrubutes = NoValue alb = t.add_resource( elb.LoadBalancer( "ApplicationLoadBalancer", DependsOn=self.log_bucket, Type="application", Scheme="internet-facing", SecurityGroups=[self.vars["PublicSecurityGroup"]], Subnets=[ subnet.strip() for subnet in self.vars["PublicSubnets"].split(",") ], LoadBalancerAttributes=lb_attrubutes, )) default_target_group = t.add_resource( elb.TargetGroup( "TargetGroup", Port="80", Protocol="HTTP", VpcId=self.vars["VpcId"], )) default_listener = t.add_resource( elb.Listener( "DefaultListener", Port="80", Protocol="HTTP", LoadBalancerArn=Ref(alb), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(default_target_group)) ], )) t.add_output( Output( "LoadBalancerArn", Description="A reference to the Application Load Balancer", Value=Ref(alb), )) t.add_output( Output( "LoadBalancerUrl", Description="URL of the ALB", Value=GetAtt(alb, "DNSName"), )) t.add_output( Output( "DefaultListener", Description="A reference to a port 80 listener", Value=Ref(default_listener), ))
def main(): """Generates the CloudFormation template""" template = Template() template.add_version("2010-09-09") # Parameters # EnvironmentName env_name_param = template.add_parameter( Parameter( 'EnvironmentName', Type='String', Description= 'An environment name that will be prefixed to resource names', )) # VPC vpc_param = 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 the Applicaion Load Balancer should be deployed to', )) # SecurityGroup sg_param = template.add_parameter( Parameter( 'SecurityGroup', Type='AWS::EC2::SecurityGroup::Id', Description= 'Select the Security Group to apply to the Applicaion Load Balancer', )) # Resources # LoadBalancer load_balancer = template.add_resource( elb.LoadBalancer('LoadBalancer', Name=Ref(env_name_param), Subnets=Ref(subnets_param), SecurityGroups=[Ref(sg_param)], Tags=[{ 'Key': 'Name', 'Value': Sub('${EnvironmentName}') }])) # DefaultTargetGroup dflt_trg_grp = template.add_resource( elb.TargetGroup('DefaultTargetGroup', Name='default', VpcId=Ref(vpc_param), Port='80', Protocol='HTTP')) # LoadBalancerListener load_balancer_listner = template.add_resource( elb.Listener('LoadBalancerListener', LoadBalancerArn=Ref(load_balancer), Port='80', Protocol='HTTP', DefaultActions=[ elb.Action(Type='forward', TargetGroupArn=Ref(dflt_trg_grp)) ])) # Output # LoadBalancer template.add_output( Output( 'LoadBalancer', Description='A reference to the Application Load Balancer', Value=Ref(load_balancer), )) template.add_output( Output( 'LoadBalancerUrl', Description='The URL of the ALB', Value=Join("", ["http://", GetAtt(load_balancer, "DNSName")]), )) template.add_output( Output( 'Listener', Description='A reference to a port 80 listener', Value=Ref(load_balancer_listner), )) print(template.to_json())
def main(): t = Template("A template to create a load balanced autoscaled Web flask deployment using ansible.") addMapping(t) ### VPC CONFIGURATION ### vpc = ec2.VPC( "MainVPC", CidrBlock="10.1.0.0/16" ) t.add_resource(vpc) vpc_id = Ref(vpc) subnet_1 = ec2.Subnet( "WebAppSubnet1", t, AvailabilityZone="us-east-1a", CidrBlock="10.1.0.0/24", MapPublicIpOnLaunch=True, VpcId=vpc_id, ) subnet_1_id = Ref(subnet_1) subnet_2 = ec2.Subnet( "WebAppSubnet2", t, AvailabilityZone="us-east-1b", CidrBlock="10.1.1.0/24", MapPublicIpOnLaunch=True, VpcId=vpc_id, ) subnet_2_id = Ref(subnet_2) ### NETWORKING ### igw = ec2.InternetGateway("internetGateway", t) gateway_to_internet = ec2.VPCGatewayAttachment( "GatewayToInternet", t, VpcId=vpc_id, InternetGatewayId=Ref(igw) ) route_table = ec2.RouteTable( "subnetRouteTable", t, VpcId=vpc_id ) route_table_id = Ref(route_table) internet_route = ec2.Route( "routeToInternet", t, DependsOn=gateway_to_internet, DestinationCidrBlock="0.0.0.0/0", GatewayId=Ref(igw), RouteTableId=route_table_id ) subnet_1_route_assoc = ec2.SubnetRouteTableAssociation( "Subnet1RouteAssociation", t, RouteTableId=route_table_id, SubnetId=Ref(subnet_1) ) subnet_2_route_assoc = ec2.SubnetRouteTableAssociation( "Subnet2RouteAssociation", t, RouteTableId=route_table_id, SubnetId=Ref(subnet_2) ) http_ingress = { "CidrIp": "0.0.0.0/0", "Description": "Allow HTTP traffic in from internet.", "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, } ssh_ingress = { "CidrIp": "0.0.0.0/0", "Description": "Allow SSH traffic in from internet.", "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, } elb_sg = ec2.SecurityGroup( "elbSecurityGroup", t, GroupName="WebGroup", GroupDescription="Allow web traffic in from internet to ELB", VpcId=vpc_id, SecurityGroupIngress=[ http_ingress ]) ssh_sg = ec2.SecurityGroup( "sshSecurityGroup", t, GroupName="SSHGroup", GroupDescription="Allow SSH traffic in from internet", VpcId=vpc_id, SecurityGroupIngress=[ ssh_ingress ] ) elb_sg_id = Ref(elb_sg) ssh_sg_id = Ref(ssh_sg) autoscale_ingress = { "SourceSecurityGroupId": elb_sg_id, "Description": "Allow web traffic in from ELB", "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80 } autoscale_sg = ec2.SecurityGroup( "WebAutoscaleSG", t, GroupName="AutoscaleGroup", GroupDescription="Allow web traffic in from elb on port 80", VpcId=vpc_id, SecurityGroupIngress=[ autoscale_ingress ] ) autoscale_sg_id = Ref(autoscale_sg) # BUCKETS app_bucket = s3.Bucket( "CodeDeployApplicationBucket", t, ) ### LOAD BALANCING ### Web_elb = elb.LoadBalancer( "WebElb", t, Name="WebElb", # TODO: Fix for name conflict Subnets=[subnet_1_id, subnet_2_id], SecurityGroups=[elb_sg_id] ) Web_target_group = elb.TargetGroup( "WebTargetGroup", t, DependsOn=Web_elb, HealthCheckPath="/health", HealthCheckPort=80, HealthCheckProtocol="HTTP", Matcher=elb.Matcher(HttpCode="200"), Name="NginxTargetGroup", Port=80, Protocol="HTTP", VpcId=vpc_id ) Web_listener = elb.Listener( "WebListener", t, LoadBalancerArn=Ref(Web_elb), DefaultActions=[ elb.Action("forwardAction", TargetGroupArn=Ref(Web_target_group), Type="forward" ) ], Port=80, Protocol="HTTP" ) ### AUTOSCALING ### # Everything after sudo -u ubuntu is one command # The sudo command is required to properly set file permissions when # running the ansible script as it assumes running from non root user lc_user_data = Base64(Join("\n", [ "#!/bin/bash", "apt-add-repository -y ppa:ansible/ansible", "apt-get update && sudo apt-get -y upgrade", "apt-get -y install git", "apt-get -y install ansible", "cd /home/ubuntu/", "sudo -H -u ubuntu bash -c '" "export LC_ALL=C.UTF-8 && " "export LANG=C.UTF-8 && " "ansible-pull -U https://github.com/DameonSmith/aws-meetup-ansible.git --extra-vars \"user=ubuntu\"'" ])) web_instance_role = iam.Role( "webInstanceCodeDeployRole", t, AssumeRolePolicyDocument={ 'Statement': [{ 'Effect': 'Allow', 'Principal': { 'Service': 'ec2.amazonaws.com' }, 'Action': 'sts:AssumeRole' }] }, Policies=[ iam.Policy( PolicyName="CodeDeployS3Policy", PolicyDocument=aws.Policy( Version='2012-10-17', Statement=[ aws.Statement( Sid='CodeDeployS3', Effect=aws.Allow, Action=[ aws_s3.PutObject, aws_s3.GetObject, aws_s3.GetObjectVersion, aws_s3.DeleteObject, aws_s3.ListObjects, aws_s3.ListBucket, aws_s3.ListBucketVersions, aws_s3.ListAllMyBuckets, aws_s3.ListMultipartUploadParts, aws_s3.ListBucketMultipartUploads, aws_s3.ListBucketByTags, ], Resource=[ GetAtt(app_bucket, 'Arn'), Join('', [ GetAtt(app_bucket, 'Arn'), '/*', ]), "arn:aws:s3:::aws-codedeploy-us-east-2/*", "arn:aws:s3:::aws-codedeploy-us-east-1/*", "arn:aws:s3:::aws-codedeploy-us-west-1/*", "arn:aws:s3:::aws-codedeploy-us-west-2/*", "arn:aws:s3:::aws-codedeploy-ca-central-1/*", "arn:aws:s3:::aws-codedeploy-eu-west-1/*", "arn:aws:s3:::aws-codedeploy-eu-west-2/*", "arn:aws:s3:::aws-codedeploy-eu-west-3/*", "arn:aws:s3:::aws-codedeploy-eu-central-1/*", "arn:aws:s3:::aws-codedeploy-ap-northeast-1/*", "arn:aws:s3:::aws-codedeploy-ap-northeast-2/*", "arn:aws:s3:::aws-codedeploy-ap-southeast-1/*", "arn:aws:s3:::aws-codedeploy-ap-southeast-2/*", "arn:aws:s3:::aws-codedeploy-ap-south-1/*", "arn:aws:s3:::aws-codedeploy-sa-east-1/*", ] ) ] ) ) ] ) web_instance_profile = iam.InstanceProfile( "webInstanceProfile", t, Path='/', Roles=[Ref(web_instance_role)], ) Web_launch_config = autoscaling.LaunchConfiguration( "webLaunchConfig", t, ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), # TODO: Remove magic string SecurityGroups=[ssh_sg_id, autoscale_sg_id], IamInstanceProfile=Ref(web_instance_profile), InstanceType="t2.micro", BlockDeviceMappings= [{ "DeviceName": "/dev/sdk", "Ebs": {"VolumeSize": "10"} }], UserData= lc_user_data, KeyName="advanced-cfn", ) Web_autoscaler = autoscaling.AutoScalingGroup( "WebAutoScaler", t, LaunchConfigurationName=Ref(Web_launch_config), MinSize="2", # TODO: Change to parameter MaxSize="2", VPCZoneIdentifier=[subnet_2_id, subnet_1_id], TargetGroupARNs= [Ref(Web_target_group)] ) t.add_output([ Output( "ALBDNS", Description="The DNS name for the application load balancer.", Value=GetAtt(Web_elb, "DNSName") ) ]) # DEVTOOLS CONFIG codebuild_service_role = iam.Role( "CMSCodeBuildServiceRole", t, AssumeRolePolicyDocument={ 'Statement': [{ 'Effect': 'Allow', 'Principal': { 'Service': ['codebuild.amazonaws.com'] }, 'Action': ['sts:AssumeRole'] }] }, Policies=[ iam.Policy( PolicyName="CloudWatchLogsPolicy", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Sid='logs', Effect=aws.Allow, Action=[ aws_logs.CreateLogGroup, aws_logs.CreateLogStream, aws_logs.PutLogEvents ], Resource=['*'] ) ] ) ), iam.Policy( PolicyName="s3AccessPolicy", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Sid='codebuilder', Effect=aws.Allow, Action=[ aws_s3.PutObject, aws_s3.GetObject, aws_s3.GetObjectVersion, aws_s3.DeleteObject ], Resource=[ GetAtt(app_bucket, 'Arn'), Join('', [ GetAtt(app_bucket, 'Arn'), '/*', ]) ] ) ] ) ) ] ) github_repo = Parameter( "GithubRepoLink", Description="Name of the repository you wish to connect to codebuild.", Type="String" ) artifact_key = Parameter( "ArtifactKey", Description="The key for the artifact that codebuild creates.", Type="String" ) t.add_parameter(github_repo) t.add_parameter(artifact_key) cms_code_build_project = codebuild.Project( "CMSBuild", t, Name="CMS-Build", Artifacts=codebuild.Artifacts( Location=Ref(app_bucket), Name=Ref(artifact_key), NamespaceType="BUILD_ID", Type="S3", Packaging="ZIP" ), Description="Code build for CMS", Environment=codebuild.Environment( ComputeType="BUILD_GENERAL1_SMALL", Image="aws/codebuild/python:3.6.5", Type="LINUX_CONTAINER", ), ServiceRole=GetAtt(codebuild_service_role, 'Arn'), Source=codebuild.Source( "CMSSourceCode", Auth=codebuild.SourceAuth( "GitHubAuth", Type="OAUTH" ), Location=Ref(github_repo), Type="GITHUB" ), Triggers=codebuild.ProjectTriggers( Webhook=True ) ) codedeploy_service_role = iam.Role( "CMSDeploymentGroupServiceRole", t, AssumeRolePolicyDocument={ 'Statement': [{ 'Effect': 'Allow', 'Principal': { 'Service': ['codedeploy.amazonaws.com'] }, 'Action': ['sts:AssumeRole'] }] }, Policies=[ iam.Policy( PolicyName="CloudWatchLogsPolicy", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Sid='logs', Effect=aws.Allow, Action=[ aws_logs.CreateLogGroup, aws_logs.CreateLogStream, aws_logs.PutLogEvents ], Resource=['*'] ) ] ) ), iam.Policy( PolicyName="s3AccessPolicy", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Sid='codebuilder', Effect=aws.Allow, Action=[ aws_s3.PutObject, aws_s3.GetObject, aws_s3.GetObjectVersion, aws_s3.DeleteObject ], Resource=[ GetAtt(app_bucket, 'Arn'), Join('', [ GetAtt(app_bucket, 'Arn'), '/*' ]) ] ) ] ) ), iam.Policy( PolicyName="autoscalingAccess", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Sid='codebuilder', Effect=aws.Allow, Action=[ aws.Action('autoscaling', '*'), aws.Action('elasticloadbalancing', '*') ], Resource=[ '*' ] ) ] ) ) ] ) cms_codedeploy_application = codedeploy.Application( "CMSCodeDeployApplication", t, ) cms_deployment_group = codedeploy.DeploymentGroup( "CMSDeploymentGroup", t, DependsOn=[cms_codedeploy_application], ApplicationName=Ref(cms_codedeploy_application), AutoScalingGroups=[Ref(Web_autoscaler)], LoadBalancerInfo=codedeploy.LoadBalancerInfo( "CodeDeployLBInfo", TargetGroupInfoList=[ codedeploy.TargetGroupInfoList( "WebTargetGroup", Name=GetAtt(Web_target_group, "TargetGroupName") ) ] ), ServiceRoleArn=GetAtt(codedeploy_service_role, 'Arn') ) print(t.to_yaml())
def main(): template = Template() template.add_resource( ecs.Cluster("ECSCluster", ClusterName="WorldCheckCluster")) template.add_resource( iam.Role("ECSTaskRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ecs-tasks.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] })) template.add_resource( iam.Role( "ECSServiceSchedulerRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ecs.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, Policies=[ iam.Policy(PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:Describe*", "elasticloadbalancing:RegisterInstancesWithLoadBalancer", "elasticloadbalancing:RegisterTargets" ], "Resource": "*" }] }, PolicyName="ecs-service") ])) template.add_resource( iam.Role("EC2InstanceRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ec2.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, Policies=[ iam.Policy(PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ecs:CreateCluster", "ecs:DeregisterContainerInstance", "ecs:DiscoverPollEndpoint", "ecs:Poll", "ecs:RegisterContainerInstance", "ecs:StartTelemetrySession", "ecr:GetAuthorizationToken", "ecr:BatchGetImage", "ecr:GetDownloadUrlForLayer", "ecs:Submit*", "logs:CreateLogStream", "logs:PutLogEvents", "ec2:DescribeTags", "cloudwatch:PutMetricData" ], "Resource": "*" }] }, PolicyName="ecs-service") ])) template.add_resource( iam.InstanceProfile("EC2InstanceProfile", Roles=[Ref("EC2InstanceRole")])) with open("user-data.sh", "r") as f: user_data_content = f.readlines() template.add_resource( ec2.Instance( "EC2Instance", ImageId="ami-13f7226a", InstanceType="t2.micro", SecurityGroups=["default"], UserData=Base64(Join('', [Sub(x) for x in user_data_content])), IamInstanceProfile=Ref("EC2InstanceProfile"), )) template.add_resource( ecs.TaskDefinition( "ECSTaskDefinition", TaskRoleArn=Ref("ECSTaskRole"), ContainerDefinitions=[ ecs.ContainerDefinition( Name="SimpleServer", Memory="128", Image="abbas123456/simple-server:latest", PortMappings=[ecs.PortMapping(ContainerPort=8000)], ) ])) template.add_resource( elb.TargetGroup( "ECSTargetGroup", VpcId="vpc-925497f6", Port=8000, Protocol="HTTP", )) template.add_resource( elb.LoadBalancer( "LoadBalancer", Subnets=["subnet-a321c8fb", "subnet-68fa271e", "subnet-689d350c"], SecurityGroups=["sg-0202bd65"])) template.add_resource( elb.Listener( "LoadBalancerListener", DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref("ECSTargetGroup")) ], LoadBalancerArn=Ref("LoadBalancer"), Port=80, Protocol="HTTP", )) template.add_resource( ecs.Service("ECSService", Cluster=Ref("ECSCluster"), DesiredCount=1, LoadBalancers=[ ecs.LoadBalancer(ContainerPort=8000, ContainerName="SimpleServer", TargetGroupArn=Ref("ECSTargetGroup")) ], Role=Ref("ECSServiceSchedulerRole"), TaskDefinition=Ref("ECSTaskDefinition"), DependsOn="LoadBalancerListener")) return template.to_json()
def main(): # Initialize template template = Template() template.set_version("2010-09-09") template.set_description("""\ Configures autoscaling group for nginx app""") # Collect template properties through parameters InstanceType = template.add_parameter( Parameter( "InstanceType", Type="String", Description="WebServer EC2 instance type", Default="t2.small", AllowedValues=[ "t2.micro", "t2.small", "t2.medium", "t2.large", "t2.xlarge" ], ConstraintDescription="Must be a valid EC2 instance type.", )) KeyName = template.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.", )) ScaleCapacity = template.add_parameter( Parameter( "ScaleCapacity", Default="1", Type="String", Description="Number of nginx servers to run", )) PublicSubnet1 = template.add_parameter( Parameter( "PublicSubnet1", Type="String", Description= "A public VPC subnet ID for the nginx app load balancer.", )) PublicSubnet2 = template.add_parameter( Parameter( "PublicSubnet2", Type="String", Description="A public VPC subnet ID for the nginx load balancer.", )) VPCAvailabilityZone2 = template.add_parameter( Parameter( "VPCAvailabilityZone2", MinLength="1", Type="String", Description="Second availability zone", MaxLength="255", )) VPCAvailabilityZone1 = template.add_parameter( Parameter( "VPCAvailabilityZone1", MinLength="1", Type="String", Description="First availability zone", MaxLength="255", )) PrivateSubnet2 = template.add_parameter( Parameter( "PrivateSubnet2", Type="String", Description="Second private VPC subnet ID for the nginx app.", )) PrivateSubnet1 = template.add_parameter( Parameter( "PrivateSubnet1", Type="String", Description="First private VPC subnet ID for the nginx app.", )) VpcId = template.add_parameter( Parameter( "VpcId", Type="String", Description="VPC Id.", )) # as of now only provide centos based ami id AmiId = template.add_parameter( Parameter( "AmiId", Type="String", Description="AMI Id.", )) # Create a common security group NginxInstanceSG = template.add_resource( ec2.SecurityGroup( "InstanceSecurityGroup", VpcId=Ref(VpcId), GroupDescription="Enable SSH and HTTP access on the inbound port", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", CidrIp="10.0.0.0/8", ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="80", ToPort="80", CidrIp="0.0.0.0/0", ) ])) # Add the application LB ApplicationElasticLB = template.add_resource( elb.LoadBalancer("ApplicationElasticLB", Name="ApplicationElasticLB", Scheme="internet-facing", Subnets=[Ref(PublicSubnet1), Ref(PublicSubnet2)], SecurityGroups=[Ref(NginxInstanceSG)])) # Add Target Group for the ALB TargetGroupNginx = template.add_resource( elb.TargetGroup( "TargetGroupNginx", VpcId=Ref(VpcId), HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher(HttpCode="200"), Name="NginxTarget", Port="80", Protocol="HTTP", UnhealthyThresholdCount="3", )) # Add ALB listener Listener = template.add_resource( elb.Listener("Listener", Port="80", Protocol="HTTP", LoadBalancerArn=Ref(ApplicationElasticLB), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(TargetGroupNginx)) ])) # Add launch configuration for auto scaling LaunchConfig = template.add_resource( LaunchConfiguration( "LaunchConfiguration", ImageId=Ref(AmiId), KeyName=Ref(KeyName), AssociatePublicIpAddress="False", LaunchConfigurationName="nginx-LC", UserData=Base64( Join('', [ "#!/bin/bash\n", "yum update\n", "yum -y install nginx\n", "chkconfig nginx on\n", "service nginx start" ])), SecurityGroups=[Ref(NginxInstanceSG)], InstanceType=Ref(InstanceType))) # Add auto scaling group AutoscalingGroup = template.add_resource( AutoScalingGroup( "AutoscalingGroup", DesiredCapacity=Ref(ScaleCapacity), LaunchConfigurationName=Ref(LaunchConfig), MinSize="1", TargetGroupARNs=[Ref(TargetGroupNginx)], MaxSize=Ref(ScaleCapacity), VPCZoneIdentifier=[Ref(PrivateSubnet1), Ref(PrivateSubnet2)], AvailabilityZones=[ Ref(VPCAvailabilityZone1), Ref(VPCAvailabilityZone2) ], HealthCheckType="EC2")) template.add_output( Output("URL", Description="URL of the sample website", Value=Join("", ["http://", GetAtt(ApplicationElasticLB, "DNSName")]))) #print(template.to_json()) with open('AutoScaling.yaml', 'w') as f: f.write(template.to_yaml())
def generate_app_load_balancer(self, lb_name, typ, port, cert_arn, log_bucket): lb_name = self.cfn_name(lb_name) if len(lb_name) >= 32: alb_name = lb_name[0:31] else: alb_name = lb_name if len(lb_name + 'TG') >= 32: tg_name = '{}TG'.format(lb_name[0:29]) else: tg_name = '{}TG'.format(lb_name) if typ not in ['internal', 'internet-facing']: raise NameError("Load balancer type must be of type internal, internet-facing") # Use the system security groups (automatic) if internal, else use the limited external security group sg = self.security_groups if typ == 'internal' else [Ref(self.elb_external_security_group)] _alb = elasticloadbalancingv2.LoadBalancer( alb_name, Name=alb_name, IpAddressType='ipv4', LoadBalancerAttributes=[ elasticloadbalancingv2.LoadBalancerAttributes( Key='access_logs.s3.enabled', Value='true' ), elasticloadbalancingv2.LoadBalancerAttributes( Key='access_logs.s3.bucket', Value=log_bucket ), elasticloadbalancingv2.LoadBalancerAttributes( Key='access_logs.s3.prefix', Value="ELB/{}/{}".format(self.env, lb_name) ), elasticloadbalancingv2.LoadBalancerAttributes( Key='deletion_protection.enabled', Value='false' ), elasticloadbalancingv2.LoadBalancerAttributes( Key='idle_timeout.timeout_seconds', Value='60' ), elasticloadbalancingv2.LoadBalancerAttributes( Key='routing.http.drop_invalid_header_fields.enabled', Value='false' ), elasticloadbalancingv2.LoadBalancerAttributes( Key='routing.http2.enabled', Value='true' ) ], Scheme=typ, SecurityGroups=sg, Subnets=[s['SubnetId'] for s in self.get_subnets('private' if typ == 'internal' else 'public')], Type='application', Tags=self.get_tags( service_override="InternalALB" if typ == 'internal' else "ExternalALB", role_override=lb_name ) + [ec2.Tag('Name', lb_name)] ) _target_group = elasticloadbalancingv2.TargetGroup( tg_name, Name=tg_name, HealthCheckIntervalSeconds=30, HealthCheckPath='/ping', HealthCheckPort=port, HealthCheckProtocol='HTTP', HealthCheckTimeoutSeconds=5, HealthyThresholdCount=5, UnhealthyThresholdCount=2, Matcher=elasticloadbalancingv2.Matcher( HttpCode='200' ), Port=port, Protocol='HTTP', TargetGroupAttributes=[ elasticloadbalancingv2.TargetGroupAttribute( Key='deregistration_delay.timeout_seconds', Value='300' ), elasticloadbalancingv2.TargetGroupAttribute( Key='stickiness.enabled', Value='false' ), elasticloadbalancingv2.TargetGroupAttribute( Key='stickiness.type', Value='lb_cookie' ), elasticloadbalancingv2.TargetGroupAttribute( Key='load_balancing.algorithm.type', Value='least_outstanding_requests' ) ], TargetType='instance', VpcId=self.vpc_id, Tags=self.get_tags( service_override="InternalALB" if typ == 'internal' else "ExternalALB", role_override=lb_name ) + [ec2.Tag('Name', '{}TG'.format(lb_name))] ) _listener_80 = self.add_resource(elasticloadbalancingv2.Listener( '{}80Listener'.format(lb_name), Port='80', Protocol='HTTP', LoadBalancerArn=Ref(_alb), DefaultActions=[ elasticloadbalancingv2.Action( Type='redirect', RedirectConfig=elasticloadbalancingv2.RedirectConfig( Host='#{host}', Path='/#{path}', Port='443', Protocol='HTTPS', Query='#{query}', StatusCode='HTTP_301' ) ) ], )) _listener_443 = self.add_resource(elasticloadbalancingv2.Listener( '{}443Listener'.format(lb_name), Port='443', Protocol='HTTPS', LoadBalancerArn=Ref(_alb), SslPolicy='ELBSecurityPolicy-2016-08', Certificates=[ elasticloadbalancingv2.Certificate( CertificateArn=cert_arn ) ], DefaultActions=[ elasticloadbalancingv2.Action( Type='forward', TargetGroupArn=Ref(_target_group) ) ], )) return _alb, _target_group
def main(): template = Template() template.add_version("2010-09-09") template.set_description("AWS CloudFormation ECS Service") # Add the Parameters Application = template.add_parameter( Parameter( "Application", Type="String", )) DockerImage = template.add_parameter( Parameter( "DockerImage", Type="String", )) USERNAME = template.add_parameter(Parameter( "USERNAME", Type="String", )) ClusterName = template.add_parameter( Parameter( "ClusterName", Type="String", )) ContainerPort = template.add_parameter( Parameter( "ContainerPort", Type="String", )) HostPort = template.add_parameter(Parameter( "HostPort", Type="String", )) HostedZoneName = template.add_parameter( Parameter( "HostedZoneName", Type="String", )) CertArn = template.add_parameter(Parameter( "CertArn", Type="String", )) ExecutionRoleArn = template.add_parameter( Parameter("ExecutionRoleArn", Type="String", Description="Execution Role to get creadentials from ssm")) HealthCheckPath = template.add_parameter( Parameter( "HealthCheckPath", Type="String", )) HealthCheckIntervalSeconds = template.add_parameter( Parameter( "HealthCheckIntervalSeconds", Type="String", )) HealthyThresholdCount = template.add_parameter( Parameter( "HealthyThresholdCount", Type="String", )) HealthCheckTimeoutSeconds = template.add_parameter( Parameter( "HealthCheckTimeoutSeconds", Type="String", )) UnhealthyThresholdCount = template.add_parameter( Parameter( "UnhealthyThresholdCount", Type="String", )) VpcId = template.add_parameter(Parameter( "VpcId", Type="String", )) Subnets = template.add_parameter( Parameter( "Subnets", Type="List<AWS::EC2::Subnet::Id>", )) # Add the application ELB NetworkLB = template.add_resource( elb.LoadBalancer("NetworkLB", Name=Join("", [Ref(Application), "-nlb"]), Scheme="internet-facing", Subnets=Ref(Subnets), Type='network')) NlbTargetGroup = template.add_resource( elb.TargetGroup( "NlbTargetGroup", Name='ecs-service-targetgroup', HealthCheckIntervalSeconds=Ref(HealthCheckIntervalSeconds), HealthCheckProtocol="TCP", HealthyThresholdCount=Ref(HealthyThresholdCount), Port=80, Protocol="TCP", UnhealthyThresholdCount=Ref(UnhealthyThresholdCount), VpcId=Ref(VpcId))) NlbListener = template.add_resource( elb.Listener( "Listener", DependsOn=["NlbTargetGroup", "NetworkLB"], Certificates=[elb.Certificate(CertificateArn=Ref(CertArn))], Port="443", Protocol="TLS", LoadBalancerArn=Ref(NetworkLB), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(NlbTargetGroup)) ])) Task_Definition = template.add_resource( TaskDefinition( 'TaskDefinition', Memory='500', ExecutionRoleArn=Ref(ExecutionRoleArn), ContainerDefinitions=[ ContainerDefinition( Name=Join("", [Ref(Application)]), Image=Ref(DockerImage), Essential=True, Secrets=[Secret(Name='USERNAME', ValueFrom=Ref(USERNAME))], Environment=[ Environment(Name="DOCKER_LABELS", Value="true") ], DockerLabels={ 'aws-account': Ref("AWS::AccountId"), 'region': Ref("AWS::Region"), 'stack': Ref("AWS::StackName") }, PortMappings=[ PortMapping(ContainerPort=Ref(ContainerPort), HostPort=Ref(HostPort)) ]) ])) app_service = template.add_resource( Service("AppService", DependsOn=["Listener", "TaskDefinition"], Cluster=Ref(ClusterName), DesiredCount=1, TaskDefinition=Ref(Task_Definition), ServiceName=Join("", [Ref(Application), "-ecs-service"]), LoadBalancers=[ ecs.LoadBalancer(ContainerName=Join( "", [Ref(Application)]), ContainerPort=Ref(ContainerPort), TargetGroupArn=Ref(NlbTargetGroup)) ])) AppDNSRecord = template.add_resource( RecordSetType( "AppDNSRecord", DependsOn=["AppService"], HostedZoneName=Join("", [Ref(HostedZoneName), "."]), Name=Join("", [Ref(Application), ".", Ref(HostedZoneName), "."]), Type="CNAME", TTL="900", ResourceRecords=[GetAtt(NetworkLB, "DNSName")])) template.add_output( Output("URL", Description="DomainName", Value=Join("", ["https://", Ref(AppDNSRecord)]))) with open("ecs-ec2-service-cf.yaml", "w") as yamlout: yamlout.write(template.to_yaml())
GroupDescription="Task Security Group", VpcId=Ref(VPC), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="80", ToPort="80", SourceSecurityGroupId=(GetAtt(ALBSecurityGroup, "GroupId")) ), ] )) # Create the ALB ALB = t.add_resource(elasticloadbalancingv2.LoadBalancer( "ALB", Scheme="internet-facing", Subnets=[Ref(PubSubnetAz1), Ref(PubSubnetAz2)], SecurityGroups=[Ref(ALBSecurityGroup)] )) # Create the ALB"s Target Group ALBTargetGroup = t.add_resource(elasticloadbalancingv2.TargetGroup( "ALBTargetGroup", HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elasticloadbalancingv2.Matcher( HttpCode="200"), Port=80, Protocol="HTTP", UnhealthyThresholdCount="3",
def add_ec2(self, ami_name, instance_type, asg_size, cidr, hosted_zone): """ Helper method creates ingress given a source cidr range and a set of ports @param ami_name [string] Name of the AMI for launching the app @param instance_type [string] Instance for the application @param asg_size [int] Sets the size of the asg @param cidr [string] Range of addresses for this vpc @param hosted_zone [string] Name of the hosted zone the elb will be mapped to """ print "Creating EC2" self.internal_security_group = self.add_sg_with_cidr_port_list( "ASGSG", "Security Group for EC2", 'vpcId', cidr, [{"443": "443"}, {"80": "80"}] ) self.public_lb_security_group = self.add_sg_with_cidr_port_list( "ELBSG", "Security Group for accessing EC2 publicly", 'vpcId', '0.0.0.0/0', [{"443": "443"}] ) name = self.env_name.replace('-', '') public_subnet_count = len(self._subnets.get('public').get('public')) public_subnets = [{'Ref': x} for x in ["publicAZ%d" % n for n in range(0, public_subnet_count)]] public_alb = self.add_resource(alb.LoadBalancer( "PublicALB", Scheme='internet-facing', Subnets=public_subnets, SecurityGroups=[Ref(sg) for sg in [self.public_lb_security_group]] )) target_group = self.add_resource(alb.TargetGroup( "AppTargetGroup80", Port=80, Protocol="HTTP", VpcId=self.vpc_id )) certificate = 'arn:aws:acm:us-east-1:422548007577:certificate/d9b8fbd2-13bb-4d6e-aba4-53061b1580f9' alb_ssl_listener = self.add_resource(alb.Listener( "ALBListner", Port=443, Certificates=[alb.Certificate(CertificateArn=certificate)], Protocol="HTTPS", DefaultActions=[alb.Action( Type="forward", TargetGroupArn=Ref(target_group))], LoadBalancerArn=Ref(public_alb) )) self.add_elb_dns_alias(public_alb, '', hosted_zone) policies = ['cloudwatchlogs'] policies_for_profile = [self.get_policy(policy, 'EC2') for policy in policies] asg = self.add_asg( "EC2", min_size=asg_size, max_size=6, ami_name=ami_name, # load_balancer=public_elb, instance_profile=self.add_instance_profile(name, policies_for_profile, name), instance_type=instance_type, security_groups=['commonSecurityGroup', Ref(self.internal_security_group)], subnet_layer='private', update_policy=UpdatePolicy( AutoScalingRollingUpdate=AutoScalingRollingUpdate( PauseTime='PT5M', MinInstancesInService=1, # The maximum number of instances that are terminated at a given time, left at 1 to ease into updates. # Can be increased at a later time MaxBatchSize='1' ) ), user_data=Base64(Join('', [ '#!/bin/bash\n', 'echo Good to go' ]))) asg.resource['Properties']['TargetGroupARNs'] = [Ref(target_group)] # Cluster Memory Scaling policies asg_scale_up_policy = self.add_resource( autoscaling.ScalingPolicy( name + 'ScaleUpPolicy', AdjustmentType='ChangeInCapacity', AutoScalingGroupName=Ref(asg), Cooldown=300, ScalingAdjustment=1 ) ) # ELB latency above a threshold self.add_resource( cloudwatch.Alarm( name + 'LatencyHigh', MetricName='Latency', ComparisonOperator='GreaterThanThreshold', Period=300, EvaluationPeriods=1, Statistic='Average', Namespace='AWS/ELB', AlarmDescription=name + 'LatencyHigh', Dimensions=[cloudwatch.MetricDimension(Name='LoadBalancerName', Value=Ref(public_alb))], Threshold='6', AlarmActions=[ Ref(asg_scale_up_policy), 'arn:aws:sns:us-east-1:422548007577:notify-pat' ] ) )
def main(): template = Template() subnetA = template.add_parameter(Parameter("subnetA", Type="String")) subnetB = template.add_parameter(Parameter("subnetB", Type="String")) alb = template.add_resource( elb.LoadBalancer( "ALB", Scheme="internet-facing", Subnets=[subnetA.ref(), subnetB.ref()], )) listener = template.add_resource( elb.Listener( "Listener", Port="80", Protocol="HTTP", LoadBalancerArn=alb.ref(), DefaultActions=[ elb.Action( Type="fixed-response", FixedResponseConfig=elb.FixedResponseConfig( StatusCode="200", MessageBody=( "This is a fixed response for the default " "ALB action"), ContentType="text/plain", ), ) ], )) template.add_resource([ elb.ListenerRule( "ListenerRuleApi", ListenerArn=listener.ref(), Conditions=[ elb.Condition(Field="host-header", Values=["api.example.com"]), elb.Condition( Field="http-header", HttpHeaderConfig=elb.HttpHeaderConfig( HttpHeaderName="X-Action", Values=["Create"]), ), elb.Condition( Field="path-pattern", PathPatternConfig=elb.PathPatternConfig(Values=["/api/*"]), ), elb.Condition( Field="http-request-method", HttpRequestMethodConfig=elb.HttpRequestMethodConfig( Values=["POST"]), ), ], Actions=[ elb.Action( Type="fixed-response", FixedResponseConfig=elb.FixedResponseConfig( StatusCode="200", MessageBody=( "This is a fixed response for any API POST " "request with header X-Action: Create"), ContentType="text/plain", ), ) ], Priority="10", ), elb.ListenerRule( "ListenerRuleWeb", ListenerArn=listener.ref(), Conditions=[ elb.Condition( Field="host-header", HostHeaderConfig=elb.HostHeaderConfig( Values=["www.example.com"]), ), elb.Condition( Field="path-pattern", PathPatternConfig=elb.PathPatternConfig(Values=["/web/*"]), ), ], Actions=[ elb.Action( Type="fixed-response", FixedResponseConfig=elb.FixedResponseConfig( StatusCode="200", MessageBody=("This is a fixed response for any WEB " "request"), ContentType="text/plain", ), ) ], Priority="20", ), elb.ListenerRule( "ListenerRuleMetrics", ListenerArn=listener.ref(), Conditions=[ elb.Condition(Field="path-pattern", Values=["/metrics/*"]) ], Actions=[ elb.Action( Type="redirect", RedirectConfig=elb.RedirectConfig(StatusCode="HTTP_301", Protocol="HTTPS", Port="443"), ) ], Priority="30", ), elb.ListenerRule( "ListenerRuleSourceIp", ListenerArn=listener.ref(), Conditions=[ elb.Condition( Field="source-ip", SourceIpConfig=elb.SourceIpConfig( Values=["52.30.12.16/28"]), ) ], Actions=[ elb.Action( Type="fixed-response", FixedResponseConfig=elb.FixedResponseConfig( StatusCode="200", MessageBody=("The request came from IP range " "52.30.12.16/28"), ContentType="text/plain", ), ) ], Priority="40", ), ]) print(template.to_json())
), ], )) t.add_resource( elb.LoadBalancer( "LoadBalancer", Scheme="internet-facing", Subnets=Split( ',', ImportValue( Join("-", [ Select(0, Split("-", Ref("AWS::StackName"))), "cluster-public-subnets" ]))), SecurityGroups=[Ref("LoadBalancerSecurityGroup")], LoadBalancerAttributes=[ elb.LoadBalancerAttributes( Key="access_logs.s3.enabled", Value="true", ), elb.LoadBalancerAttributes( Key="access_logs.s3.bucket", Value=Ref("S3Bucket"), ) ], )) t.add_resource( elb.TargetGroup( "TargetGroup", DependsOn='LoadBalancer',
ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="3000", ToPort="3000", CidrIp="0.0.0.0/0", ), ], )) t.add_resource( elb.LoadBalancer( "LoadBalancer", Scheme="internet-facing", Subnets=Split( ',', ImportValue( Join("-", [ Select(0, Split("-", Ref("AWS::StackName"))), "cluster-public-subnets" ]))), SecurityGroups=[Ref("LoadBalancerSecurityGroup")], )) t.add_resource( elb.TargetGroup( "TargetGroup", DependsOn='LoadBalancer', HealthCheckIntervalSeconds="20", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="15", HealthyThresholdCount="5", Matcher=elb.Matcher(HttpCode="200"),
DependsOn="InvokePermission")) t.add_resource( Permission( "InvokePermission", Action="lambda:InvokeFunction", FunctionName=GetAtt(app_function, 'Arn'), Principal="elasticloadbalancing.amazonaws.com", #SourceArn=Ref(targetGroup) # This would create a creation loop #SourceAccount=Ref('AWS::AccountId') )) # Add the application ELB ApplicationElasticLB = t.add_resource( elb.LoadBalancer("ApplicationElasticLB", Name="ApplicationElasticLB", Scheme="internet-facing", Subnets=[x["SubnetId"] for x in subnets])) t.add_resource( elb.Listener("Listener", LoadBalancerArn=Ref(ApplicationElasticLB), Port=80, Protocol="HTTP", DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(targetGroup)) ])) t.add_output([ Output("LoadbalancerArn", Value=Ref(ApplicationElasticLB)), Output("LoadbalancerDNSName",
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
InstanceType='t2.micro', NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[Ref(instance_sg)], AssociatePublicIpAddress='true', DeviceIndex='0', SubnetId=Ref(subnet2) ) ] ) ) application_elb = t.add_resource( elb.LoadBalancer( "TestELB", Name="TestELB", Scheme="internet-facing", Subnets=[Ref(subnet1), Ref(subnet2)] ) ) target_group_web = t.add_resource( elb.TargetGroup( "TestTargetGroupWeb", HealthCheckIntervalSeconds="60", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="30", HealthyThresholdCount="4", UnhealthyThresholdCount="3", Matcher=elb.Matcher(HttpCode="200"), Name="WebTarget", Port="8080",
def generate_template(d): # Set template metadata t = Template() t.add_version("2010-09-09") t.set_description(d["cf_template_description"]) # aws_account_id = Ref("AWS::AccountId") # aws_region = Ref("AWS::Region") # ALB SG ALBSG = t.add_resource( SecurityGroup( "ALBSG", GroupDescription="Enable HTTP access.", SecurityGroupIngress=[ SecurityGroupRule(IpProtocol="tcp", FromPort="80", ToPort="80", CidrIp="0.0.0.0/0") ], VpcId=ImportValue(d["network_stack_name"] + "-VPCId"), )) # ALB ALB = t.add_resource( elb.LoadBalancer( "ALB", Name=d["project_name"], Scheme="internet-facing", SecurityGroups=[Ref("ALBSG")], Subnets=[ ImportValue(d["network_stack_name"] + "-PublicSubnetId1"), ImportValue(d["network_stack_name"] + "-PublicSubnetId2"), ], Tags=Tags(d["tags"]), )) # ECS cluster ECSCluster = t.add_resource( Cluster("ECSCluster", ClusterName=d["project_name"], Tags=Tags(d["tags"]))) # ECS cluster SG ClusterSG = t.add_resource( SecurityGroup( "ClusterSG", GroupDescription="Enable HTTP access.", SecurityGroupIngress=[ SecurityGroupRule( IpProtocol="tcp", FromPort="0", ToPort="65535", SourceSecurityGroupId=Ref(ALBSG), ) ], VpcId=ImportValue(d["network_stack_name"] + "-VPCId"), )) # ALB listener listener80 = t.add_resource( elb.Listener( "Listener80", Port="80", Protocol="HTTP", LoadBalancerArn=Ref("ALB"), DefaultActions=[ elb.Action( Type="fixed-response", FixedResponseConfig=elb.FixedResponseConfig( StatusCode="200", MessageBody=( "This is a fixed response for the default " "ALB action"), ContentType="text/plain", ), ) ], )) # ECS service role ECSClusterRole = t.add_resource( Role("ECSClusterRole", RoleName="ECSClusterRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole", }], })) # ECS Cluster Role Policy t.add_resource( PolicyType( 'ECSClusterRolePolicy', PolicyName="ECSCLusterRolePolicy", Roles=[Ref(ECSClusterRole)], PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Sid": "ECSTaskManagement", "Effect": "Allow", "Action": [ "ec2:AttachNetworkInterface", "ec2:CreateNetworkInterface", "ec2:CreateNetworkInterfacePermission", "ec2:DeleteNetworkInterface", "ec2:DeleteNetworkInterfacePermission", "ec2:Describe*", "ec2:DetachNetworkInterface", "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:Describe*", "elasticloadbalancing:RegisterInstancesWithLoadBalancer", "elasticloadbalancing:RegisterTargets", "route53:ChangeResourceRecordSets", "route53:CreateHealthCheck", "route53:DeleteHealthCheck", "route53:Get*", "route53:List*", "route53:UpdateHealthCheck", "servicediscovery:DeregisterInstance", "servicediscovery:Get*", "servicediscovery:List*", "servicediscovery:RegisterInstance", "servicediscovery:UpdateInstanceCustomHealthStatus", "ecr:*", "cloudwatch:*", "logs:*", "iam:*", ], "Resource": "*" }, { "Sid": "AutoScaling", "Effect": "Allow", "Action": ["autoscaling:Describe*"], "Resource": "*" }, { "Sid": "AutoScalingManagement", "Effect": "Allow", "Action": [ "autoscaling:DeletePolicy", "autoscaling:PutScalingPolicy", "autoscaling:SetInstanceProtection", "autoscaling:UpdateAutoScalingGroup" ], "Resource": "*", "Condition": { "Null": { "autoscaling:ResourceTag/AmazonECSManaged": "false" } } }, { "Sid": "AutoScalingPlanManagement", "Effect": "Allow", "Action": [ "autoscaling-plans:CreateScalingPlan", "autoscaling-plans:DeleteScalingPlan", "autoscaling-plans:DescribeScalingPlans" ], "Resource": "*" }, { "Sid": "CWAlarmManagement", "Effect": "Allow", "Action": [ "cloudwatch:DeleteAlarms", "cloudwatch:DescribeAlarms", "cloudwatch:PutMetricAlarm" ], "Resource": "arn:aws:cloudwatch:*:*:alarm:*" }, { "Sid": "ECSTagging", "Effect": "Allow", "Action": ["ec2:CreateTags"], "Resource": "arn:aws:ec2:*:*:network-interface/*" }, { "Sid": "CWLogGroupManagement", "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:DescribeLogGroups", "logs:PutRetentionPolicy" ], "Resource": "arn:aws:logs:*:*:log-group:/aws/ecs/*" }, { "Sid": "CWLogStreamManagement", "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:log-group:/aws/ecs/*:log-stream:*" }] })) # Codebuild role CodebuildDeveloperRole = t.add_resource( Role("CodebuildDeveloperRole", RoleName="CodebuilDevelopRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "codebuild.amazonaws.com" }, "Action": "sts:AssumeRole", }], })) # Codebuild developer role policy t.add_resource( PolicyType( 'CodebuildDeveloperRolePolicy', PolicyName="CodebuildDeveloperRolePolicy", Roles=[Ref(CodebuildDeveloperRole)], PolicyDocument={ "Statement": [{ "Action": [ "codebuild:StartBuild", "codebuild:StopBuild", "codebuild:BatchGet*", "codebuild:GetResourcePolicy", "codebuild:DescribeTestCases", "codebuild:List*", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetRepository", "codecommit:ListBranches", "cloudwatch:GetMetricStatistics", "events:DescribeRule", "events:ListTargetsByRule", "events:ListRuleNamesByTarget", "logs:GetLogEvents", "s3:*", "logs:*", "ecr:*" ], "Effect": "Allow", "Resource": "*" }, { "Effect": "Allow", "Action": ["ssm:PutParameter"], "Resource": "arn:aws:ssm:*:*:parameter/CodeBuild/*" }, { "Sid": "CodeStarNotificationsReadWriteAccess", "Effect": "Allow", "Action": [ "codestar-notifications:CreateNotificationRule", "codestar-notifications:DescribeNotificationRule", "codestar-notifications:UpdateNotificationRule", "codestar-notifications:Subscribe", "codestar-notifications:Unsubscribe" ], "Resource": "*", "Condition": { "StringLike": { "codestar-notifications:NotificationsForResource": "arn:aws:codebuild:*" } } }, { "Sid": "CodeStarNotificationsListAccess", "Effect": "Allow", "Action": [ "codestar-notifications:ListNotificationRules", "codestar-notifications:ListEventTypes", "codestar-notifications:ListTargets", "codestar-notifications:ListTagsforResource" ], "Resource": "*" }, { "Sid": "SNSTopicListAccess", "Effect": "Allow", "Action": ["sns:ListTopics", "sns:GetTopicAttributes"], "Resource": "*" }], "Version": "2012-10-17" })) # Codepipeline role CodePipelineRole = t.add_resource( Role("CodePipelineRole", RoleName="CodePipelineRole", AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "codepipeline.amazonaws.com" }, "Action": "sts:AssumeRole", }], })) t.add_resource( PolicyType( 'CodePipelineRolePolicy', PolicyName="CodePipelineRolePolicy", Roles=[Ref(CodePipelineRole)], PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Action": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:ValidateTemplate", "iam:PassRole", "s3:*", ], "Resource": "*", "Effect": "Allow" }, { "Action": ["codebuild:BatchGetBuilds", "codebuild:StartBuild"], "Resource": "*", "Effect": "Allow" }, { "Action": ["ecr:*"], "Resource": "*", "Effect": "Allow" }, { "Action": [ "ecs:DescribeServices", "ecs:DescribeTaskDefinition", "ecs:DescribeTasks", "ecs:ListTasks", "ecs:RegisterTaskDefinition", "ecs:UpdateService" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codedeploy:CreateDeployment", "codedeploy:GetDeployment", "codedeploy:GetApplication", "codedeploy:GetApplicationRevision", "codedeploy:RegisterApplicationRevision", "codedeploy:GetDeploymentConfig", "ecs:RegisterTaskDefinition", "iam:PassRole" ], "Resource": "*", "Effect": "Allow" }] })) # Outputs # ListenerArnHTTP t.add_output( Output( "ListenerArnHTTP", Description="Listener Arn (HTTP) of the newly created Listener", Export=Export(Sub("${AWS::StackName}-ListenerArnHTTP")), Value=Ref(listener80), )) t.add_output( Output( "ECSClusterRole", Description="ECS Cluster role with managed policy", Export=Export(Sub("${AWS::StackName}-ECSClusterRole")), Value=GetAtt(ECSClusterRole, "Arn"), )) t.add_output( Output( "CodePipelineRole", Description="CodePipeline role with managed policy", Export=Export(Sub("${AWS::StackName}-CodePipelineRole")), Value=GetAtt(CodePipelineRole, "Arn"), )) t.add_output( Output( "CodebuildDeveloperRole", Description="Codebuild role with managed policy", Export=Export(Sub("${AWS::StackName}-CodebuildDeveloperRole")), Value=GetAtt(CodebuildDeveloperRole, "Arn"), )) t.add_output( Output( "ECSClusterName", Description="ECS cluster name.", Export=Export(Sub("${AWS::StackName}-ECSClusterName")), # Value=GetAtt(ECSCluster, "Arn"), Value=Ref(ECSCluster), )) t.add_output( Output( "ALB", Description="ALB name.", Export=Export(Sub("${AWS::StackName}-ALBName")), Value=GetAtt(ALB, "LoadBalancerName"), )) t.add_output( Output( "ECSClusterSG", Description="ECS Cluster SG name.", Export=Export(Sub("${AWS::StackName}-ECSClusterSG")), Value=Ref(ClusterSG), )) return t
def main(): template = Template() template.add_version("2010-09-09") template.add_description( "AWS CloudFormation Sample Template: ELB with 2 EC2 instances") AddAMI(template) # Add the Parameters keyname_param = template.add_parameter( Parameter( "KeyName", Type='AWS::EC2::KeyPair::KeyName', Default="ansible-key", Description="Name of an existing EC2 KeyPair to " "enable SSH access to the instance", )) template.add_parameter( Parameter( "InstanceType", Type="String", Description="WebServer EC2 instance type", Default="t2.micro", AllowedValues=["t1.micro", "t2.micro"], ConstraintDescription="must be a valid EC2 instance type.", )) webport_param = template.add_parameter( Parameter( "WebServerPort", Type="String", Default="8888", Description="TCP/IP port of the web server", )) web2_param = template.add_parameter( Parameter( "ApiServerPort", Type="String", Default="8889", Description="TCP/IP port of the api server", )) subnetA = template.add_parameter( Parameter("subnetA", Type="List<AWS::EC2::Subnet::Id>", Description="Choose Subnets")) VpcId = template.add_parameter( Parameter("VpcId", Type="AWS::EC2::VPC::Id", Description="Choose VPC")) # Define the instance security group instance_sg = template.add_resource( ec2.SecurityGroup( "InstanceSecurityGroup", GroupDescription="Enable SSH and HTTP access on the inbound port", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", CidrIp="0.0.0.0/0", ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=Ref(webport_param), ToPort=Ref(webport_param), CidrIp="0.0.0.0/0", ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=Ref(web2_param), ToPort=Ref(web2_param), CidrIp="0.0.0.0/0", ), ])) # Add the web server instance WebInstance = template.add_resource( ec2.Instance( "WebInstance", SecurityGroups=[Ref(instance_sg)], KeyName=Ref(keyname_param), InstanceType=Ref("InstanceType"), ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), UserData=Base64( Join('', [ '#!/bin/bash\n', 'sudo yum -y update\n', 'sudo yum install -y httpd php\n', 'sudo sed -i "42s/Listen 80/Listen 8888/" /etc/httpd/conf/httpd.conf\n', 'sudo service httpd restart \n', 'Ref(webport_param)', ])))) # Add the api server instance ApiInstance = template.add_resource( ec2.Instance( "ApiInstance", SecurityGroups=[Ref(instance_sg)], KeyName=Ref(keyname_param), InstanceType=Ref("InstanceType"), ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), UserData=Base64( Join('', [ '#!/bin/bash\n', 'sudo yum -y update\n', 'sudo yum install -y httpd php\n', 'sudo sed -i "42s/Listen 80/Listen 8889/" /etc/httpd/conf/httpd.conf\n', 'sudo service httpd restart \n', 'Ref(web2_param)', ])))) # Add the application ELB ApplicationElasticLB = template.add_resource( elb.LoadBalancer("ApplicationElasticLB", Name="ApplicationElasticLB", Scheme="internet-facing", Subnets=Ref("subnetA"))) TargetGroupWeb = template.add_resource( elb.TargetGroup("TargetGroupWeb", HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher(HttpCode="200"), Name="WebTarget", Port=Ref(webport_param), Protocol="HTTP", Targets=[ elb.TargetDescription(Id=Ref(WebInstance), Port=Ref(webport_param)) ], UnhealthyThresholdCount="3", VpcId=Ref(VpcId))) TargetGroupApi = template.add_resource( elb.TargetGroup("TargetGroupApi", HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher(HttpCode="200"), Name="ApiTarget", Port=Ref(web2_param), Protocol="HTTP", Targets=[ elb.TargetDescription(Id=Ref(ApiInstance), Port=Ref(web2_param)) ], UnhealthyThresholdCount="3", VpcId=Ref(VpcId))) Listener = template.add_resource( elb.Listener("Listener", Port="80", Protocol="HTTP", LoadBalancerArn=Ref(ApplicationElasticLB), DefaultActions=[ elb.Action(Type="forward", TargetGroupArn=Ref(TargetGroupWeb)) ])) template.add_resource( elb.ListenerRule("ListenerRuleApi", ListenerArn=Ref(Listener), Conditions=[ elb.Condition(Field="path-pattern", Values=["/api/*"]) ], Actions=[ elb.Action(Type="forward", TargetGroupArn=Ref(TargetGroupApi)) ], Priority="1")) template.add_output( Output("URL", Description="URL of the sample website", Value=Join("", ["http://", GetAtt(ApplicationElasticLB, "DNSName")]))) print(template.to_json())
def main(): template = Template() template.add_version("2010-09-09") template.add_description( "AWS CloudFormation Sample Template: ELB with 2 EC2 instances") AddAMI(template) # Add the Parameters keyname_param = template.add_parameter(Parameter( "KeyName", Type="String", Default="mark", Description="Name of an existing EC2 KeyPair to " "enable SSH access to the instance", )) template.add_parameter(Parameter( "InstanceType", Type="String", Description="WebServer EC2 instance type", Default="m1.small", AllowedValues=[ "t1.micro", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge", "cc2.8xlarge", "cg1.4xlarge" ], ConstraintDescription="must be a valid EC2 instance type.", )) webport_param = template.add_parameter(Parameter( "WebServerPort", Type="String", Default="8888", Description="TCP/IP port of the web server", )) apiport_param = template.add_parameter(Parameter( "ApiServerPort", Type="String", Default="8889", Description="TCP/IP port of the api server", )) subnetA = template.add_parameter(Parameter( "subnetA", Type="String", Default="subnet-096fd06d" )) subnetB = template.add_parameter(Parameter( "subnetB", Type="String", Default="subnet-1313ef4b" )) VpcId = template.add_parameter(Parameter( "VpcId", Type="String", Default="vpc-82c514e6" )) # Define the instance security group instance_sg = template.add_resource( ec2.SecurityGroup( "InstanceSecurityGroup", GroupDescription="Enable SSH and HTTP access on the inbound port", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", CidrIp="0.0.0.0/0", ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=Ref(webport_param), ToPort=Ref(webport_param), CidrIp="0.0.0.0/0", ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=Ref(apiport_param), ToPort=Ref(apiport_param), CidrIp="0.0.0.0/0", ), ] ) ) # Add the web server instance WebInstance = template.add_resource(ec2.Instance( "WebInstance", SecurityGroups=[Ref(instance_sg)], KeyName=Ref(keyname_param), InstanceType=Ref("InstanceType"), ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), UserData=Base64(Ref(webport_param)), )) # Add the api server instance ApiInstance = template.add_resource(ec2.Instance( "ApiInstance", SecurityGroups=[Ref(instance_sg)], KeyName=Ref(keyname_param), InstanceType=Ref("InstanceType"), ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), UserData=Base64(Ref(apiport_param)), )) # Add the application ELB ApplicationElasticLB = template.add_resource(elb.LoadBalancer( "ApplicationElasticLB", Name="ApplicationElasticLB", Scheme="internet-facing", Subnets=[Ref(subnetA), Ref(subnetB)] )) TargetGroupWeb = template.add_resource(elb.TargetGroup( "TargetGroupWeb", HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher( HttpCode="200"), Name="WebTarget", Port=Ref(webport_param), Protocol="HTTP", Targets=[elb.TargetDescription( Id=Ref(WebInstance), Port=Ref(webport_param))], UnhealthyThresholdCount="3", VpcId=Ref(VpcId) )) TargetGroupApi = template.add_resource(elb.TargetGroup( "TargetGroupApi", HealthCheckIntervalSeconds="30", HealthCheckProtocol="HTTP", HealthCheckTimeoutSeconds="10", HealthyThresholdCount="4", Matcher=elb.Matcher( HttpCode="200"), Name="ApiTarget", Port=Ref(apiport_param), Protocol="HTTP", Targets=[elb.TargetDescription( Id=Ref(ApiInstance), Port=Ref(apiport_param))], UnhealthyThresholdCount="3", VpcId=Ref(VpcId) )) Listener = template.add_resource(elb.Listener( "Listener", Port="80", Protocol="HTTP", LoadBalancerArn=Ref(ApplicationElasticLB), DefaultActions=[elb.Action( Type="forward", TargetGroupArn=Ref(TargetGroupWeb) )] )) template.add_resource(elb.ListenerRule( "ListenerRuleApi", ListenerArn=Ref(Listener), Conditions=[elb.Condition( Field="path-pattern", Values=["/api/*"])], Actions=[elb.Action( Type="forward", TargetGroupArn=Ref(TargetGroupApi) )], Priority="1" )) template.add_output(Output( "URL", Description="URL of the sample website", Value=Join("", ["http://", GetAtt(ApplicationElasticLB, "DNSName")]) )) print(template.to_json())
'CMD-SHELL', 'php -v || exit 1' ], Interval=30, Retries=3, Timeout=5 ) )] ) ) # Create the load balancer. load_balancer = template.add_resource( elb.LoadBalancer( 'LoadBalancer', Scheme='internet-facing', SecurityGroups=[GetAtt(load_balancer_security_group, 'GroupId')], Subnets=Ref(subnets), ) ) api_target_group = template.add_resource( elb.TargetGroup( 'ApiTargetGroup', HealthCheckIntervalSeconds=30, HealthCheckPath='/', HealthCheckPort='traffic-port', HealthCheckProtocol='HTTP', HealthCheckTimeoutSeconds=5, HealthyThresholdCount=5, UnhealthyThresholdCount=2, Port=80,