Example #1
0
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'),
        ),
    ]
Example #2
0
def create_target_group(stack,
                        name,
                        port,
                        protocol='HTTPS',
                        targets=[],
                        http_codes='200',
                        health_check_path='/',
                        target_type='instance',
                        attributes=False):
    """Add Target Group Resource."""
    target_objects = []

    for target in targets:
        target_objects.append(alb.TargetDescription(Id=target))

    tg_atts = []

    if not attributes:
        tg_atts.append(
            alb.TargetGroupAttribute(
                Key='deregistration_delay.timeout_seconds', Value='300'))
    else:
        for att, value in attributes.items():
            tg_atts.append(alb.TargetGroupAttribute(Key=att, Value=value))

    if http_codes is not None:
        return stack.stack.add_resource(
            alb.TargetGroup('{0}TargetGroup'.format(name),
                            HealthCheckIntervalSeconds='30',
                            HealthCheckProtocol=protocol,
                            HealthCheckTimeoutSeconds='10',
                            HealthyThresholdCount='4',
                            HealthCheckPath=health_check_path,
                            Matcher=alb.Matcher(HttpCode=http_codes),
                            Name='{0}Target'.format(name),
                            Port=port,
                            Protocol=protocol,
                            Targets=target_objects,
                            TargetType=target_type,
                            UnhealthyThresholdCount='3',
                            TargetGroupAttributes=tg_atts,
                            VpcId=Ref(stack.vpc)))

    return stack.stack.add_resource(
        alb.TargetGroup('{0}TargetGroup'.format(name),
                        HealthCheckIntervalSeconds='30',
                        HealthCheckProtocol=protocol,
                        HealthCheckTimeoutSeconds='10',
                        HealthyThresholdCount='3',
                        Name='{0}Target'.format(name),
                        Port=port,
                        Protocol=protocol,
                        Targets=targets,
                        UnhealthyThresholdCount='3',
                        TargetType=target_type,
                        TargetGroupAttributes=tg_atts,
                        VpcId=Ref(stack.vpc)))
Example #3
0
    def add_resources(self):
        """Add resources to template."""
        template = self.template
        variables = self.get_variables()

        targetgroup = template.add_resource(
            elasticloadbalancingv2.TargetGroup(
                'TargetGroup',
                HealthCheckIntervalSeconds=variables[
                    'HealthCheckIntervalSeconds'].ref,
                HealthCheckPath=variables['HealthCheckPath'].ref,
                HealthCheckPort=variables['HealthCheckPort'].ref,
                HealthCheckProtocol=variables['HealthCheckProtocol'].ref,
                HealthCheckTimeoutSeconds=variables[
                    'HealthCheckTimeoutSeconds'].ref,
                HealthyThresholdCount=variables['HealthyThresholdCount'].ref,
                UnhealthyThresholdCount=variables['UnhealthyThresholdCount'].
                ref,
                Matcher=elasticloadbalancingv2.Matcher(
                    HttpCode=variables['HealthCheckSuccessCodes'].ref),
                Name=variables['TargetGroupName'].ref,
                Port=variables['AppPort'].ref,
                Protocol=variables['AppProtocol'].ref,
                Tags=Tags(Application=variables['ApplicationName'].ref,
                          Environment=variables['EnvironmentName'].ref),
                TargetType=variables['TargetType'].ref,
                VpcId=variables['VpcId'].ref))

        template.add_output(
            Output("{}Arn".format(targetgroup.title),
                   Description="ARN of the Target Group",
                   Value=Ref(targetgroup),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % targetgroup.title))))
    def configure_alb(self, t, service):
        service_target_group = t.add_resource(elasticloadbalancingv2.TargetGroup(
            self.resource_name_format % ('ServiceTargetGroup'),
            Port=80,
            Protocol="HTTP",
            HealthCheckPath=self.healthcheck_path,
            HealthCheckIntervalSeconds=self.healthcheck_interval,
            HealthCheckTimeoutSeconds=self.healthcheck_interval - 1,
            HealthyThresholdCount=2,
            UnhealthyThresholdCount=5,
            VpcId=ImportValue(Sub(self.imports_format % ('VpcId'))),
            TargetGroupAttributes=[
                elasticloadbalancingv2.TargetGroupAttribute(Key=key, Value=value)
                for (key, value) in sorted(self.target_group_attributes().items())
            ]
        ))

        listener_rule = t.add_resource(elasticloadbalancingv2.ListenerRule(
            self.resource_name_format % ('SecureListenerRule'),
            ListenerArn=ImportValue(Sub(self.imports_format % ('PublicListener' if self.public else 'InternalListener'))),
            Priority=self.priority,
            Actions=[elasticloadbalancingv2.Action(Type="forward", TargetGroupArn=Ref(service_target_group))],
            Conditions=[elasticloadbalancingv2.Condition(Field="host-header", Values=self.domains)]
        ))

        service.DependsOn.append(listener_rule.title)
        service.LoadBalancers = [
            ecs.LoadBalancer(
                ContainerName=self.container_name,
                ContainerPort=self.port,
                TargetGroupArn=Ref(service_target_group)
            )
        ]
Example #5
0
    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
Example #6
0
 def gen_default_target_group(self):
     self.default_target_group = elasticloadbalancingv2.TargetGroup(
         "DefaultTargetGroup",
         VpcId=self.import_value("vpc", "VPC"),
         Port="80",
         TargetType="ip",
         Protocol="HTTP",
     )
     self.template.add_resource(self.default_target_group)
Example #7
0
    def create_default_target_group(self, template):
        """

        :param template:
        :param instance_name:
        """
        template.add_resource(
            alb.TargetGroup(
                TARGET_GROUP_DEFAULT,
                Port='80',
                Protocol="HTTP",
                VpcId=Ref("VpcId"),
            ))
Example #8
0
 def gen_target_group(self):
     self.target_group = elasticloadbalancingv2.TargetGroup(
         "TargetGroup",
         VpcId=self.import_value("vpc", "VPC"),
         Port="80",
         TargetGroupAttributes=[
             elasticloadbalancingv2.TargetGroupAttribute(
                 Key="deregistration_delay.timeout_seconds", Value="10"),
         ],
         TargetType="ip",
         Protocol="HTTP",
         HealthCheckPath="/demo",
     )
     self.template.add_resource(self.target_group)
Example #9
0
    def handle(self, chain_context):
        chain_context.metadata[META_TARGET_GROUP_NAME] = self.name
        template = chain_context.template

        template.add_resource(
            alb.TargetGroup(self.name,
                            HealthCheckPath="/",
                            HealthCheckIntervalSeconds="30",
                            HealthCheckProtocol="HTTP",
                            HealthCheckTimeoutSeconds="10",
                            HealthyThresholdCount="4",
                            Matcher=alb.Matcher(HttpCode="200"),
                            Port=self.port,
                            Protocol="HTTP",
                            UnhealthyThresholdCount="3",
                            VpcId=self.vpc_id))
def create_api_tarcreate_group_resource(template, vpc_parameter,
                                        load_balancer_resource):
    return template.add_resource(
        elb.TargetGroup('ApiTargetGroup',
                        HealthCheckIntervalSeconds=30,
                        HealthCheckPath='/',
                        HealthCheckPort='traffic-port',
                        HealthCheckProtocol='HTTP',
                        HealthCheckTimeoutSeconds=5,
                        HealthyThresholdCount=5,
                        UnhealthyThresholdCount=2,
                        Port=80,
                        Protocol='HTTP',
                        TargetType='instance',
                        VpcId=Ref(vpc_parameter),
                        DependsOn=[load_balancer_resource]))
Example #11
0
File: elb.py Project: yarlevi/pyaws
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
Example #12
0
 def create_target_group(self):
     t = self.template
     required_attributes = dict(
         Port=self.vars['ContainerPort'],
         Protocol=self.vars['TargetGroupProtocol'],
         TargetType='ip',
         VpcId=self.vars['VpcId'],
     )
     if self.vars['HealthCheckAttributes']:
         if 'Matcher' in self.vars['HealthCheckAttributes']:
             self.vars['HealthCheckAttributes']['Matcher'] = elb.Matcher(
                 **self.vars['HealthCheckAttributes']['Matcher'])
         tg_attributes = self.vars['HealthCheckAttributes'].copy()
     else:
         tg_attributes = dict()
     tg_attributes.update(required_attributes)
     return t.add_resource(elb.TargetGroup("TargetGroup", **tg_attributes))
Example #13
0
    def handle(self, chain_context):

        # todo: why is this not allowing a reference?

        name = '%sTargetGroup' % chain_context.instance_name

        chain_context.metadata[META_TARGET_GROUP_NAME] = name
        template = chain_context.template

        template.add_resource(alb.TargetGroup(
            name,
            HealthCheckPath="/",
            HealthCheckIntervalSeconds="30",
            HealthCheckProtocol="HTTP",
            HealthCheckTimeoutSeconds="10",
            HealthyThresholdCount="4",
            Matcher=alb.Matcher(HttpCode="200"),
            Port=self.port,
            Protocol="HTTP",
            UnhealthyThresholdCount="3",
            VpcId=self.vpc_id
        ))
Example #14
0
                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"),
        Port=3000,
        Protocol="HTTP",
        UnhealthyThresholdCount="3",
        VpcId=ImportValue(
            Join("-", [
                Select(0, Split("-", Ref("AWS::StackName"))), "cluster-vpc-id"
            ])),
    ))

t.add_resource(
    elb.Listener("Listener",
                 Port="3000",
                 Protocol="HTTP",
                 LoadBalancerArn=Ref("LoadBalancer"),
                 DefaultActions=[
                     elb.Action(Type="forward",
Example #15
0
    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',
    LoadBalancerArn=Ref(ourelb),
    DefaultActions=[elb.Action(
        Type="forward",
        TargetGroupArn=Ref(webserver_target_group),
    )]
))

Example #16
0
    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())
Example #18
0
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())
Example #19
0
    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():
    # 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())
Example #21
0
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())
Example #22
0
        '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,
        Protocol='HTTP',
        TargetType='instance',
        VpcId=Ref(vpc),
        DependsOn=[load_balancer]
    )
)

load_balancer_listener = template.add_resource(
    elb.Listener(
        'LoadBalancerListener',
        LoadBalancerArn=Ref(load_balancer),
        Port=443,
        Protocol='HTTPS',
# 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",
    TargetType="ip",
    VpcId=Ref(VPC)
))

ALBListener = t.add_resource(elasticloadbalancingv2.Listener(
    "ALBListener",
    Port="80",
    Protocol="HTTP",
    LoadBalancerArn=Ref(ALB),
    DefaultActions=[elasticloadbalancingv2.Action(
        Type="forward",
        TargetGroupArn=Ref(ALBTargetGroup)
    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'
                ]
            )
        )
Example #25
0
        Environment=Environment(Variables={
            "RUST_BACKTRACE": "1",
            "RUST_LOG": "debug"
        }),
        Handler="not_used",
        Role=GetAtt(LambdaExecutionRole, "Arn"),
        Runtime="provided",
    ))

ec2_client = boto3.client('ec2')
subnets = ec2_client.describe_subnets()["Subnets"]

targetGroup = t.add_resource(
    elb.TargetGroup(
        "TargetGroup",
        TargetType="lambda",
        Targets=[elb.TargetDescription(Id=GetAtt(app_function, 'Arn'))],
        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(
Example #26
0
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()
Example #27
0
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
Example #28
0
        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",
        Protocol="HTTP",
        Targets=[elb.TargetDescription(
            Id=Ref(web_instance),
            Port="8080"
        )],
        VpcId=Ref(vpc)
    )
)

target_group_api = t.add_resource(
    elb.TargetGroup(
        "TestTargetGroupApi",
        HealthCheckIntervalSeconds="30",
        HealthCheckProtocol="HTTP",
Example #29
0
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())
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())