Example #1
0
def create_alb_template():
    template = Template()

    vpc = template.add_parameter(
        parameter=Parameter(title='Vpc', Type='String'))
    subnet_a = template.add_parameter(
        parameter=Parameter(title='SubnetA', Type='String'))
    subnet_b = template.add_parameter(
        parameter=Parameter(title='SubnetB', Type='String'))
    ec2_instance = template.add_parameter(
        parameter=Parameter(title='Ec2Instance', Type='String'))

    security_group = template.add_resource(
        resource=SecurityGroup(title='SampleSecurityGroup',
                               GroupDescription='sample-security-group',
                               SecurityGroupIngress=[{
                                   'IpProtocol': 'tcp',
                                   'FromPort': 80,
                                   'ToPort': 80,
                                   'CidrIp': '0.0.0.0/0'
                               }],
                               VpcId=Ref(vpc)))

    load_balancer = template.add_resource(resource=LoadBalancer(
        title='SampleLoadBalancer',
        Name='sample-alb',
        Subnets=[Ref(subnet_a), Ref(subnet_b)],
        SecurityGroups=[Ref(security_group)],
    ))

    target_group = template.add_resource(resource=TargetGroup(
        title='SampleTargetGroup',
        Targets=[TargetDescription(
            Id=Ref(ec2_instance),
            Port=80,
        )],
        VpcId=Ref(vpc),
        Name='sample-target-group',
        Port=80,
        Protocol='HTTP',
    ))

    template.add_resource(resource=Listener(
        title='SampleListener',
        DefaultActions=[
            Action(TargetGroupArn=Ref(target_group), Type='forward')
        ],
        LoadBalancerArn=Ref(load_balancer),
        Port=80,
        Protocol='HTTP',
    ))

    with open('./alb.yml', mode='w') as file:
        file.write(template.to_yaml())
Example #2
0
 def to_target_desc(self):
     ret = TargetDescription(Id=self.host, Port=self.port)
     if self.type == "ip":
         # TODO: Support specifying the AZ
         ret.AvailabilityZone = "all"
     return ret
Example #3
0
    def to_json(self):
        if self._json is not None:
            return self._json

        # Validity checks
        if len(self.subnet_ids) < 2:
            raise ValidationException(
                "Use .subnet_id() to specify at least two ELB subnets")
        if len(self.cert_ids) < 1:
            raise ValidationException(
                "Use .certificate_id() to specify at least one certificate")
        if not self._ecs_redirect and len(self.default_targets) < 1:
            raise ValidationException(
                "Use .default_target() to specify at least one default target or .ecs_redirect("
                ") to set up a redirect container")
        for (name, tp) in self.target_paths.iteritems():
            if len(set(map(lambda h: h.type, tp.hosts))) != 1:
                raise ValidationException(
                    "Inconsistent target types for %s. All hosts for a given path must have the "
                    "same type (ip or instance)." % name)

        # Build Security Group
        if self._custom_elb_sgs:
            elb_sgs = self._custom_elb_sgs
        else:
            elb_sg = SecurityGroup(
                "ElbSecurityGroup",
                GroupDescription=Sub("${AWS::StackName}-ElbSg"),
                Tags=self.tags_with(Name=Sub("${AWS::StackName}-ElbSg")),
                VpcId=self.vpc_id,
                SecurityGroupEgress=[
                    SecurityGroupRule(CidrIp="0.0.0.0/0", IpProtocol="-1")
                ],
                SecurityGroupIngress=self._sg_rules)
            self.template.add_resource(elb_sg)
            self.template.add_output(
                Output("ElbSecurityGroupOutput",
                       Description="Security group ID assigned to the ELB",
                       Value=Ref(elb_sg),
                       Export=Export(Sub("${AWS::StackName}-ElbSg"))))

            # Build Attachment Security Group
            inst_sg = SecurityGroup(
                "InstanceSecurityGroup",
                GroupDescription=Sub("${AWS::StackName}-InstSg"),
                Tags=self.tags_with(Name=Sub("${AWS::StackName}-InstSg")),
                VpcId=self.vpc_id,
                SecurityGroupEgress=[
                    SecurityGroupRule(CidrIp="0.0.0.0/0", IpProtocol="-1")
                ],
                SecurityGroupIngress=[
                    SecurityGroupRule(IpProtocol="-1",
                                      SourceSecurityGroupId=Ref(elb_sg))
                ])
            self.template.add_resource(inst_sg)
            self.template.add_output(
                Output("InstanceSecurityGroupOutput",
                       Description="Convenience SG to assign to instances",
                       Value=Ref(inst_sg),
                       Export=Export(Sub("${AWS::StackName}-InstSg"))))
            elb_sgs = [Ref("ElbSecurityGroup")]

        # Build ELB
        elb = LoadBalancer("ELB",
                           Name=Ref("AWS::StackName"),
                           SecurityGroups=elb_sgs,
                           Subnets=self.subnet_ids,
                           Tags=self.tags_with(Name=Ref("AWS::StackName")),
                           LoadBalancerAttributes=self.elb_attributes())
        self.template.add_resource(elb)
        self.template.add_output(
            Output("ElbArnOutput",
                   Description="ARN of the ELB",
                   Value=Ref(elb),
                   Export=Export(Sub("${AWS::StackName}-ElbArn"))))
        self.template.add_output(
            Output("ElbDnsOutput",
                   Description="DNS name of the ELB",
                   Value=GetAtt("ELB", "DNSName"),
                   Export=Export(Sub("${AWS::StackName}-ElbDns"))))

        # Build Default Target Group
        if self._ecs_redirect:
            default_tg_protocol = "HTTP"
        else:
            default_tg_protocol = self.default_targets[0].protocol
        default_tg = TargetGroup(
            "DefaultTargetGroup",
            Port=8080,
            Protocol=default_tg_protocol,
            Tags=self.tags_with(Name=Sub("${AWS::StackName}-Default")),
            VpcId=self.vpc_id,
            Targets=list(
                map(lambda h: TargetDescription(Id=h.host, Port=h.port),
                    self.default_targets)),
            HealthyThresholdCount=2,
            Matcher=Matcher(HttpCode="200-399"))
        self.template.add_resource(default_tg)
        self.attach_alarm(default_tg)

        # Build Listener
        self.template.add_resource(
            Listener("HttpsListener",
                     Certificates=list(
                         map(lambda i: Certificate(CertificateArn=i),
                             self.cert_ids)),
                     DefaultActions=[
                         Action(Type="forward",
                                TargetGroupArn=Ref("DefaultTargetGroup"))
                     ],
                     LoadBalancerArn=Ref("ELB"),
                     Port=443,
                     Protocol="HTTPS"))

        # Build HTTP redirect
        if len(self.http_redirect_targets) > 0:
            # Build Redirect Target Group
            http_tg = TargetGroup(
                "RedirectTargetGroup",
                Port=8080,
                Protocol=self.http_redirect_targets[0].protocol,
                Tags=self.tags_with(Name=Sub("${AWS::StackName}-Redirect")),
                VpcId=self.vpc_id,
                Targets=list(
                    map(lambda h: TargetDescription(Id=h.host, Port=h.port),
                        self.http_redirect_targets)),
                HealthyThresholdCount=2,
                Matcher=Matcher(HttpCode="200-399"))
            self.template.add_resource(http_tg)
            self.attach_alarm(http_tg)

        if self._ecs_redirect or len(self.http_redirect_targets) > 0:
            if self._ecs_redirect:
                redirect_tg = "DefaultTargetGroup"
            else:
                redirect_tg = "RedirectTargetGroup"
            # Build Listener
            self.template.add_resource(
                Listener("HttpListener",
                         DefaultActions=[
                             Action(Type="forward",
                                    TargetGroupArn=Ref(redirect_tg))
                         ],
                         LoadBalancerArn=Ref("ELB"),
                         Port=80,
                         Protocol="HTTP"))

        # Build Target Groups & Rules
        for (name, tp) in self.target_paths.iteritems():
            name_an = alpha_numeric_name(name)
            tag_name = taggable_name(name)

            g = TargetGroup(
                "PathTg" + name_an,
                Port=tp.hosts[0].port,
                Protocol=tp.hosts[0].protocol,
                Tags=self.tags_with(Name="%s/%s" % (self.env_name, tag_name),
                                    TargetPath=tag_name),
                Targets=list(map(lambda h: h.to_target_desc(), tp.hosts)),
                VpcId=self.vpc_id,
                HealthCheckPath="/%s" % name,
                HealthyThresholdCount=2,
                Matcher=tp.health_check_matcher)

            # TODO: We should probably explicitly specify this for every TG. Not
            #       doing that now because it will cause lots of updates. Maybe
            #       in 0.4?
            if len(tp.hosts) > 0 and tp.hosts[0].type != "instance":
                g.TargetType = tp.hosts[0].type

            if self.sticky:
                g.TargetGroupAttributes = [
                    TargetGroupAttribute(Key="stickiness.enabled",
                                         Value="true"),
                    TargetGroupAttribute(Key="stickiness.type",
                                         Value="lb_cookie")
                ]
            self.template.add_resource(g)
            self.attach_alarm(g)
            self.template.add_resource(
                ListenerRule(
                    "PathRl" + name_an,
                    Actions=[Action(Type="forward", TargetGroupArn=Ref(g))],
                    Conditions=[
                        Condition(Field="path-pattern",
                                  Values=["/%s/*" % name])
                    ],
                    ListenerArn=Ref("HttpsListener"),
                    Priority=self.priority_hash(name)))
            self.template.add_resource(
                ListenerRule(
                    "PathRln" + name_an,
                    Actions=[Action(Type="forward", TargetGroupArn=Ref(g))],
                    Conditions=[
                        Condition(Field="path-pattern", Values=["/%s" % name])
                    ],
                    ListenerArn=Ref("HttpsListener"),
                    Priority=self.priority_hash(name)))

        # Build Alternate Listeners
        for al in self.alt_listeners:
            tg_name = "AltTg%d" % al.port
            tg_protocol = al.hosts[0].protocol
            tg = TargetGroup(
                tg_name,
                Port=9999,
                Protocol=tg_protocol,
                Tags=self.tags_with(Name=Sub("${AWS::StackName}-%s" %
                                             tg_name)),
                VpcId=self.vpc_id,
                Targets=list(
                    map(lambda h: TargetDescription(Id=h.host, Port=h.port),
                        al.hosts)),
                HealthyThresholdCount=2,
                Matcher=Matcher(HttpCode="200-399"))
            self.template.add_resource(tg)
            self.attach_alarm(tg)

            listener = Listener("AltListener%d" % al.port,
                                DefaultActions=[
                                    Action(Type="forward",
                                           TargetGroupArn=Ref(tg_name))
                                ],
                                LoadBalancerArn=Ref("ELB"),
                                Port=al.port,
                                Protocol=al.protocol)

            if al.protocol == "HTTPS":
                listener.Certificates = list(
                    map(lambda i: Certificate(CertificateArn=i),
                        self.cert_ids))

            self.template.add_resource(listener)

        self._json = self.template.to_json()
        return self._json
Example #4
0
def create_alb_template():
    template = Template()

    vpc = template.add_parameter(
        parameter=Parameter(title='Vpc', Type='String'))
    subnet_a = template.add_parameter(
        parameter=Parameter(title='SubnetA', Type='String'))
    subnet_b = template.add_parameter(
        parameter=Parameter(title='SubnetB', Type='String'))
    ec2_instance = template.add_parameter(
        parameter=Parameter(title='Ec2Instance', Type='String'))
    certificate = template.add_parameter(
        parameter=Parameter(title='Certificate', Type='String'))

    security_group = template.add_resource(
        resource=SecurityGroup(title='SampleSecurityGroup',
                               GroupDescription='sample-security-group',
                               SecurityGroupIngress=[{
                                   'IpProtocol': 'tcp',
                                   'FromPort': 80,
                                   'ToPort': 80,
                                   'CidrIp': '0.0.0.0/0'
                               }, {
                                   'IpProtocol': 'tcp',
                                   'FromPort': 443,
                                   'ToPort': 443,
                                   'CidrIp': '0.0.0.0/0'
                               }],
                               VpcId=Ref(vpc)))

    load_balancer = template.add_resource(resource=LoadBalancer(
        title='SampleLoadBalancer',
        Name='sample-alb-https',
        Subnets=[Ref(subnet_a), Ref(subnet_b)],
        SecurityGroups=[Ref(security_group)],
    ))

    target_group = template.add_resource(resource=TargetGroup(
        title='SampleTargetGroup',
        Targets=[TargetDescription(
            Id=Ref(ec2_instance),
            Port=80,
        )],
        VpcId=Ref(vpc),
        Name='sample-target-group-https',
        Port=443,
        Protocol='HTTP',
    ))

    template.add_resource(resource=Listener(
        title='SampleListenerHttps',
        Certificates=[Certificate(CertificateArn=Ref(certificate))],
        DefaultActions=[
            Action(TargetGroupArn=Ref(target_group), Type='forward')
        ],
        LoadBalancerArn=Ref(load_balancer),
        Port=443,
        Protocol='HTTPS',
    ))

    template.add_resource(resource=Listener(
        title='SampleListenerHttp',
        DefaultActions=[
            Action(
                RedirectConfig=RedirectConfig(
                    Host='#{host}',
                    Path='/#{path}',
                    Port='443',
                    Protocol='HTTPS',
                    Query='#{query}',
                    StatusCode='HTTP_301',
                ),
                Type='redirect',
            )
        ],
        LoadBalancerArn=Ref(load_balancer),
        Port=80,
        Protocol='HTTP',
    ))

    with open('./alb.yml', mode='w') as file:
        file.write(template.to_yaml())