def create_load_balancer(self): t = self.template t.add_resource( elb.LoadBalancer( "LoadBalancer", HealthCheck=elb.HealthCheck(Target="HTTP:8081/health", HealthyThreshold=3, UnhealthyThreshold=3, Interval=5, Timeout=3), ConnectionSettings=elb.ConnectionSettings( IdleTimeout=3600), # 1 hour Listeners=self.setup_listeners(), SecurityGroups=[ Ref(ELB_SG_NAME), ], Subnets=Ref("PublicSubnets"))) # Setup ELB DNS t.add_resource( RecordSetType("ElbDnsRecord", HostedZoneName=Join("", [Ref("ExternalDomain"), "."]), Comment="Router ELB DNS", Name=Join(".", ["empire", Ref("ExternalDomain")]), Type="CNAME", TTL="120", ResourceRecords=[GetAtt("LoadBalancer", "DNSName")]))
def __init__(self, title, **kwargs): super().__init__(title, **kwargs) self.AccessLoggingPolicy = If( 'LoadBalancerLog', elb.AccessLoggingPolicy( EmitInterval=get_endvalue('LoadBalancerLog'), Enabled=True, S3BucketName=Sub(cfg.BucketLogs), S3BucketPrefix=''), Ref('AWS::NoValue')) self.ConnectionDrainingPolicy = elb.ConnectionDrainingPolicy( Enabled=True, Timeout=5) self.ConnectionSettings = elb.ConnectionSettings( IdleTimeout=get_endvalue('LoadBalancerIdleTimeout')) self.CrossZone = True self.HealthCheck = elb.HealthCheck( HealthyThreshold=get_endvalue('HealthyThresholdCount'), Interval=get_endvalue('HealthCheckIntervalSeconds'), Target=get_endvalue('HealthCheckTarget'), Timeout=get_endvalue('HealthCheckTimeoutSeconds'), UnhealthyThreshold=get_endvalue('UnhealthyThresholdCount')) self.LBCookieStickinessPolicy = If('LoadBalancerCookieSticky', [ elb.LBCookieStickinessPolicy(PolicyName='LBCookieStickinessPolicy', CookieExpirationPeriod=get_endvalue( 'LoadBalancerCookieSticky')) ], Ref('AWS::NoValue')) self.SecurityGroups = [GetAtt('SecurityGroupLoadBalancer', 'GroupId')]
def render_elb(context, template, ec2_instances): elb_is_public = True if context['full_hostname'] else False listeners_policy_names = [] app_cookie_stickiness_policy = [] lb_cookie_stickiness_policy = [] if context['elb']['stickiness']: if context['elb']['stickiness']['type'] == 'cookie': app_cookie_stickiness_policy = [ elb.AppCookieStickinessPolicy( CookieName=context['elb']['stickiness']['cookie-name'], PolicyName='AppCookieStickinessPolicy') ] listeners_policy_names.append('AppCookieStickinessPolicy') elif context['elb']['stickiness']['type'] == 'browser': lb_cookie_stickiness_policy = [ elb.LBCookieStickinessPolicy( PolicyName='BrowserSessionLongCookieStickinessPolicy') ] listeners_policy_names.append( 'BrowserSessionLongCookieStickinessPolicy') else: raise ValueError('Unsupported stickiness: %s' % context['elb']['stickiness']) protocols = _elb_protocols(context) listeners = [] elb_ports = [] for protocol in protocols: if protocol == 'http': listeners.append( elb.Listener( InstanceProtocol='HTTP', InstancePort='80', LoadBalancerPort='80', PolicyNames=listeners_policy_names, Protocol='HTTP', )) elb_ports.append(80) elif protocol == 'https': listeners.append( elb.Listener(InstanceProtocol='HTTP', InstancePort='80', LoadBalancerPort='443', PolicyNames=listeners_policy_names, Protocol='HTTPS', SSLCertificateId=context['elb']['certificate'])) elb_ports.append(443) elif isinstance(protocol, int): port = protocol listeners.append( elb.Listener(InstanceProtocol='TCP', InstancePort=str(port), LoadBalancerPort=str(port), PolicyNames=listeners_policy_names, Protocol='TCP')) elb_ports.append(port) else: raise RuntimeError("Unknown procotol `%s`" % context['elb']['protocol']) for _, listener in context['elb']['additional_listeners'].items(): listeners.append( elb.Listener(InstanceProtocol='HTTP', InstancePort=str(listener['port']), LoadBalancerPort=str(listener['port']), PolicyNames=listeners_policy_names, Protocol=listener['protocol'].upper(), SSLCertificateId=context['elb']['certificate'])) elb_ports.append(listener['port']) template.add_resource( elb.LoadBalancer( ELB_TITLE, AppCookieStickinessPolicy=app_cookie_stickiness_policy, ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy( Enabled=True, Timeout=60, ), ConnectionSettings=elb.ConnectionSettings( IdleTimeout=context['elb']['idle_timeout']), CrossZone=True, Instances=lmap(Ref, ec2_instances.values()), # TODO: from configuration Listeners=listeners, LBCookieStickinessPolicy=lb_cookie_stickiness_policy, HealthCheck=elb.HealthCheck( Target=_elb_healthcheck_target(context), HealthyThreshold=str(context['elb']['healthcheck'].get( 'healthy_threshold', 10)), UnhealthyThreshold=str(context['elb']['healthcheck'].get( 'unhealthy_threshold', 2)), Interval=str(context['elb']['healthcheck'].get('interval', 30)), Timeout=str(context['elb']['healthcheck'].get('timeout', 30)), ), SecurityGroups=[Ref(SECURITY_GROUP_ELB_TITLE)], Scheme='internet-facing' if elb_is_public else 'internal', Subnets=context['elb']['subnets'], Tags=elb_tags(context))) template.add_output( mkoutput("ElasticLoadBalancer", "Generated name of the ELB", Ref(ELB_TITLE))) template.add_resource( security_group(SECURITY_GROUP_ELB_TITLE, context['aws']['vpc-id'], _convert_ports_to_dictionary( elb_ports))) # list of strings or dicts if any([context['full_hostname'], context['int_full_hostname']]): dns = external_dns_elb if elb_is_public else internal_dns_elb template.add_resource(dns(context)) if context['full_hostname']: [template.add_resource(cname) for cname in cnames(context)]
def render_elb(context, template, ec2_instances): ensure(any([context['full_hostname'], context['int_full_hostname']]), "An ELB must have either an external or an internal DNS entry") elb_is_public = True if context['full_hostname'] else False listeners_policy_names = [] if context['elb']['stickiness']: cookie_stickiness = [ elb.LBCookieStickinessPolicy( PolicyName="BrowserSessionLongCookieStickinessPolicy") ] listeners_policy_names.append( 'BrowserSessionLongCookieStickinessPolicy') else: cookie_stickiness = [] if context['elb']['protocol'] == 'http': listeners = [ elb.Listener( InstanceProtocol='HTTP', InstancePort='80', LoadBalancerPort='80', PolicyNames=listeners_policy_names, Protocol='HTTP', ), ] elif context['elb']['protocol'] == 'https': listeners = [ elb.Listener(InstanceProtocol='HTTP', InstancePort='80', LoadBalancerPort='443', PolicyNames=listeners_policy_names, Protocol='HTTPS', SSLCertificateId=context['elb']['certificate']), ] else: raise RuntimeError("Unknown procotol `%s`" % context['elb']['protocol']) template.add_resource( elb.LoadBalancer( ELB_TITLE, ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy( Enabled=True, Timeout=60, ), ConnectionSettings=elb.ConnectionSettings( IdleTimeout=context['elb']['idle_timeout']), CrossZone=True, Instances=map(Ref, ec2_instances), # TODO: from configuration Listeners=listeners, LBCookieStickinessPolicy=cookie_stickiness, # TODO: from configuration # seems to default to opening a TCP connection on port 80 # HealthCheck=elb.HealthCheck( # Target=Join('', ['HTTP:', Ref(webport_param), '/']), # HealthyThreshold='3', # UnhealthyThreshold='5', # Interval='30', # Timeout='5', # ) SecurityGroups=[Ref(SECURITY_GROUP_TITLE)], Scheme='internet-facing' if elb_is_public else 'internal', Subnets=context['elb']['subnets'], Tags=elb_tags(context))) dns = external_dns_elb if elb_is_public else internal_dns_elb template.add_resource(dns(context))
def generate_load_balancer(self, lb_name, typ, port, cert_arn, log_bucket): lb_name = self.cfn_name(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)] return elasticloadbalancing.LoadBalancer( lb_name, AccessLoggingPolicy=elasticloadbalancing.AccessLoggingPolicy( EmitInterval=60, Enabled=True, S3BucketName=log_bucket, S3BucketPrefix="ELB/{}/{}".format(self.env, lb_name) ), ConnectionDrainingPolicy=elasticloadbalancing.ConnectionDrainingPolicy( Enabled=True, Timeout=60 ), ConnectionSettings=elasticloadbalancing.ConnectionSettings( IdleTimeout=3600 ), CrossZone=False, HealthCheck=elasticloadbalancing.HealthCheck( HealthyThreshold=5, Interval=30, Target='HTTP:{}/ping'.format(port), Timeout=5, UnhealthyThreshold=2 ), LoadBalancerName=lb_name, Listeners=[ elasticloadbalancing.Listener( InstancePort=port, InstanceProtocol='HTTP', LoadBalancerPort=80, Protocol='HTTP' ), elasticloadbalancing.Listener( InstancePort=port, InstanceProtocol='HTTP', LoadBalancerPort=443, Protocol='HTTPS', SSLCertificateId=cert_arn ), elasticloadbalancing.Listener( InstancePort=port, InstanceProtocol='TCP', LoadBalancerPort=8443, Protocol='SSL', SSLCertificateId=cert_arn ) ], Policies=[ elasticloadbalancing.Policy( PolicyName='ELBSecurityPolicyNoTLS10', PolicyType='SSLNegotiationPolicyType', Attributes=[{ 'Name': 'Reference-Security-Policy', # Disable TLS 1.0 and migrate to TLS 1.2 default for external ELB 'Value': 'ELBSecurityPolicy-TLS-1-2-2017-01' }] ) ], Scheme=typ, SecurityGroups=sg, Subnets=[s['SubnetId'] for s in self.get_subnets('private' if typ == 'internal' else 'public')], Tags=self.get_tags( service_override="InternalELB" if typ == 'internal' else "ExternalELB", role_override=lb_name ) + [ec2.Tag('Name', lb_name)] )