首页 > 解决方案 > 如何在将 Troposhpere 框架用于 AWS 经典负载均衡器 443 侦听器时更新 SSL 协商策略

问题描述

我有一个有效的对流层模板,它使用经典的负载均衡器来构建我的环境。我正在修改它以使用 SSL 协商策略(密码)ELBSecurityPolicy-TLS-1-2-2017-01 启动负载均衡器端口 443 侦听器。

它会让我生成 cloudformation yaml,但是当我尝试使用生成的 yaml 创建堆栈时,我在尝试创建负载均衡器时收到错误“遇到不支持的属性 PolicyType”。

Troposphere 支持 PolicyType,但 AWS CF 不支持?

关于我做错了什么的任何线索?有没有更好的办法?

我找不到任何使用对流层框架更新 SSL 协商的示例。

这是我认为应该发挥作用的对流层 ELB 侦听器代码部分的片段 -

            LoadBalancerPort="443",
            InstancePort="443",
            Protocol="https",
            InstanceProtocol="https",
            PolicyNames=["StickyPolicy", "My-SSLNegotiation-Policy"],
            #todo - need valid cert
            SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Policy(
            LoadBalancerPorts=["443"],
            InstancePorts=["443"],
            PolicyType="SSLNegotiationPolicyType",
            PolicyName="My-SSLNegotiation-Policy",
            Attributes=[{
            "Name": "Reference-Security-Policy",
            "Value": "ELBSecurityPolicy-TLS-1-2-2017-01"
            }]
        )`

这是对流层 elasticloadbalancing.py 的策略类(https://github.com/cloudtools/troposphere/blob/master/troposphere/elasticloadbalancing.py

class Policy(AWSProperty):
    props = {
        'Attributes': ([dict], False),
        'InstancePorts': (list, False),
        'LoadBalancerPorts': (list, False),
        'PolicyName': (basestring, True),
        'PolicyType': (basestring, True),
    }

这是我的整个对流层负载均衡器代码:

LoadBalancer = t.add_resource(LoadBalancer(
#https://github.com/cloudtools/troposphere/blob/master/examples/Autoscaling.py
    "LoadBalancer",
    ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
        Enabled=True,
        Timeout=120,
    ),
    ConnectionSettings=elb.ConnectionSettings(
        IdleTimeout=600
    ),
    Subnets=[DMZSubnet1a, DMZSubnet1b],
    LBCookieStickinessPolicy=[elb.LBCookieStickinessPolicy(
        PolicyName="StickyPolicy",
        CookieExpirationPeriod="28800"
        ),
    ],
    #AvailabilityZones=[Join("", [Ref("AWS::Region"), "a"]), Join("", [Ref("AWS::Region"), "b"])],
    HealthCheck=elb.HealthCheck(
        #Target="HTTPS:443/index.html",
        Target="TCP:80",
        HealthyThreshold="5",
        UnhealthyThreshold="5",
        Interval="30",
        Timeout="15",
    ),
    # Redirect http to https on classic load balancer   -  https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/
    Listeners=[
        elb.Listener(
            LoadBalancerPort="80",
            InstancePort="80",
            Protocol="TCP",
            InstanceProtocol="TCP",
            #SSLCertificateId=Ref(SSLCertificateId)
            #SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Listener(
            LoadBalancerPort="443",
            InstancePort="443",
            Protocol="https",
            InstanceProtocol="https",
            PolicyNames=["StickyPolicy", "My-SSLNegotiation-Policy"],
            #todo - need valid cert
            SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Policy(
            LoadBalancerPorts=["443"],
            InstancePorts=["443"],
            PolicyType="SSLNegotiationPolicyType",
            PolicyName="My-SSLNegotiation-Policy",
            Attributes=[{
            "Name": "Reference-Security-Policy",
            "Value": "ELBSecurityPolicy-TLS-1-2-2017-01"
            }]
        )
    ],
    CrossZone=True,
    SecurityGroups=[LoadBalancerSG],
    LoadBalancerName=Join("-", [Ref("AWS::StackName"), "LdBlncr"]),
    Scheme="internet-facing",
))

这是它为负载均衡器创建的 AWS CloudFormation yaml:

  LoadBalancer:
    Properties:
      ConnectionDrainingPolicy:
        Enabled: true
        Timeout: 120
      ConnectionSettings:
        IdleTimeout: 600
      CrossZone: 'true'
      HealthCheck:
        HealthyThreshold: '5'
        Interval: '30'
        Target: TCP:80
        Timeout: '15'
        UnhealthyThreshold: '5'
      LBCookieStickinessPolicy:
        - CookieExpirationPeriod: '28800'
          PolicyName: StickyPolicy
      Listeners:
        - InstancePort: '80'
          InstanceProtocol: TCP
          LoadBalancerPort: '80'
          Protocol: TCP
        - InstancePort: '443'
          InstanceProtocol: https
          LoadBalancerPort: '443'
          PolicyNames:
            - StickyPolicy
            - My-SSLNegotiation-Policy
          Protocol: https
          SSLCertificateId: arn:aws:acm:us-east-1:000000000:certificate/d79e336-dd51-4cac-ba3
        - Attributes:
            - Name: Reference-Security-Policy
              Value: ELBSecurityPolicy-TLS-1-2-2017-01
          InstancePorts:
            - '443'
          LoadBalancerPorts:
            - '443'
          PolicyName: My-SSLNegotiation-Policy
          PolicyType: SSLNegotiationPolicyType
      LoadBalancerName: !Join
        - '-'
        - - !Ref 'AWS::StackName'
          - LdBlncr
      Scheme: internet-facing
      SecurityGroups:
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - LoadBalancerSG
      Subnets:
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - DMZSubnet1a
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - DMZSubnet1b
    Type: AWS::ElasticLoadBalancing::LoadBalancer

标签: amazon-web-servicesamazon-elbtroposphere

解决方案


Classic Load Balancer Policies 应在 Policies 属性下指定,而不是 Listeners 属性。https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html#cfn-ec2-elb-policies

elb.Policy( ... )Listerners=[ ...]属性中移除 并将属性添加Policies = [ elb.Policy( ... ), ... ]到 LoadBalancer 资源/对象。


推荐阅读