Associate multiple SSL certificates with a single load balancer within a CloudFormation template
Did you know AWS supports associating multiple SSL certificates to a Single Load balancer listener? Here is how you can do that in a CloudFormation template.
Lets say you have 2 APIs
api.car-booking.com. You can have a single Application Load Balancer which can serve both these services. You do that with a Load Balancer Listener. I have explained in another post how you can use a single load balancer to serve multiple services on the same domain, but for now lets concentrate on the task at hand, viz., associating multiple SSL certificates to a single Listener using a CloudFormation Template. The following diagram shows the rough architecture where you have a Load Balancer with a Listener which has 2 Rules each resolving to a target group.
Now lets secure these services by adding SSL certificates for both the domains. Once you import the SSL certificates for
api.car-booking.com into AWS Certificate Manager, you can get the certificate ARN from the Certificate Manager console. You can then use the following CloudFormation template as a guide
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 AWSTemplateFormatVersion: 2010-09-09 Parameters: ExistingVPC: Type: String Description: 'Existing VPC ID. REQUIRED' ExistingSubnets: Type: CommaDelimitedList Description: 'Existing subnets within the Existing VPC. REQUIRED' CertificateARN1: Type: String Description: 'SSL certificate ARN for api.hotel-booking-com' CertificateARN2: Type: String Description: 'SSL certificate ARN for api.car-booking.com' Resources: LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing SecurityGroups: - !GetAtt LoadBalancerSecurityGroup.GroupId Subnets: !Ref ExistingSubnets LoadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 'Enable access to load balancer' VpcId: !Ref ExistingVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 LoadBalancerListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref LoadBalancerListenerDefaultGroup Type: forward LoadBalancerArn: !Ref LoadBalancer Port: 443 Protocol: HTTPS Certificates: - CertificateArn: !Ref CertificateARN1 LoadBalancerAdditionalCertificates: Type: AWS::ElasticLoadBalancingV2::ListenerCertificate Properties: Certificates: - CertificateArn: !Ref CertificateARN1 ListenerArn: !Ref LoadBalancerListener LoadBalancerListenerDefaultGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 80 Protocol: HTTP VpcId: !Ref ExistingVPC
Take a note of the resource
AWS::ElasticLoadBalancingV2::Listener, line 33. Though we are assoicating multiple SSL certificates with the listener, we are passing only One certificate ARN under
Certificates, line 43. The key
Certificates looks like a list and yes it is a list, which can be really misleading and as a newbie you might pass multiple ARNs to it, and get an error when executed
If you read the documentation for AWS::ElasticLoadBalancingV2::Listener carefully, it reads
The default SSL server certificate for a secure listener. You must provide exactly one certificate if the listener protocol is HTTPS or TLS.
The correct way to go about is to add another resource of type
AWS::ElasticLoadBalancingV2::ListenerCertificate where you can pass multiple certificate ARNs and then associate the resource with the listener. If you check the Listener on AWS console, you will see both the certificates are now associated with it. Now you can add target groups to this listener where you can specify rules based on the host header. As mentioned earlier, I will elaborate in another post how to add target groups to achieve this, but for now assuming that part is already done, when users reach the load balancer with either
api.car-booking.com the correct SSL certificate will be picked up.
It is what we know already that often prevents us from learning.- Claude Bernard