I have a working Troposphere template that brings up my environment with a classic load balancer. I am modifying it to have the load balancer port 443 listener come up using the SSL Negotiation policy(cypher) ELBSecurityPolicy-TLS-1-2-2017-01.
It will let me generate the cloudformation yaml but when I try to create the stack using the generated yaml I get the error "Encountered unsupported property PolicyType" while it is trying to create the load balancer.
PolicyType is supported by Troposphere but not in AWS CF??
Any clues as to what I am doing wrong? Is there a better way?
I can not find any examples of updating the SSL negotiation using the Troposphere framework.
Here is the snippet of my Troposphere ELB listener code section that I think should do the magic -
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"
}]
)`
Here is the policy class for the Troposphere 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),
}
Here is my entire Troposphere load balancer code :
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",
))
Here is the AWS CloudFormation yaml it creates for the load balancer :
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
The Classic Load Balancer Policies should be specified under the Policies property, not the Listeners property. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html#cfn-ec2-elb-policies
Remove the elb.Policy( ... )
from the Listerners=[ ...]
property and add the Policies = [ elb.Policy( ... ), ... ]
property to the LoadBalancer resource / object.