Search code examples
amazon-web-servicesdockercontainersamazon-elbamazon-alb

Load Balancing multiple Containerized Applications on a Group of Instances


The hypothetical scenario is you have 3 containerized (docker) web applications using different ports -- 1234, 5678, 7890.

Is it possible to have an Application Load Balancer that forwards HTTP/HTTPS traffic from app1.example.com, app2.example.com, and app3.example.com to a specific port on an EC2 Target Group?

Example: All traffic coming from app1.example.com should go to the port 1234 of the EC2 Target Group.

Also, what would be the SSL Certificate Setup for this since the ELB will be having multiple subdomains?


Solution

    1. In order to do this, first you'll need to create 3 separate target groups, each containing the same EC2's you want to redirect to, differentiated by the target port for each application (1234, 5678, etc).

    2. Once you do this, you can create a new ALB with 2 listeners, one for HTTP on port 80, and another for HTTPS on port 443. If you're creating this through the AWS Console, set the availability zones you want to use, choose a security policy and certificate for the HTTPS listener, and choose or create a security group. For the routing configuration, just create some new arbitrary target group. We're going to simply delete it later (the wizard won't let you select the appropriate options on creation).

    3. Once the ALB is created, we need to edit the rules of the 2 listeners. So select the ALB, go to the listeners tab, and click on the 'View/edit rules' link next to one of the listeners (Note this is NOT selecting the listener and clicking 'Edit', which is something entirely different). Now on this new screen, click on the pencil to edit the current default rule, delete the current 'THEN' action, and replace it with 'Return fixed response...'. For the fields here, I would just set a Response code of 400, with the response body being something like 'invalid host header'. This will only be returned if a client tries to access this load balancer with a host other than the ones we'll explicitly set.

    4. Now click the 'Update' button to save the changes for this default rule, and then click the '+' button to add a new rule above the default rule. For this new rule, add the condition 'Host is...', and set it to one of the app domains (i.e. app1.example.com). Now add the condition for this rule to 'Forward to...', and select the target group for this app that you created earlier.

    5. Now repeat step 4 for all apps you need to service for this load balancer

    6. Now repeat steps 3-5 for the other listener on the ALB

    7. You can now delete the extra target group you may have made earlier during the creation of the ALB via the wizard in the console. Other than that, you should be done.

    Note: There is no way to have a single HTTPS listener use multiple different certificates, even though you can route based on the host header. In order for SSL to be valid across multiple different apps, you will be REQUIRED to use a wildcard certificate that is valid for all your apps at the same time. If you use ACM, you can generate free wildcard certificates and use them on the ALB.

    Edit 9/12/2019: AWS Now offers SNI with their NLBs, which means that you can now use multiple different TLS certificates for a single load balancer: https://aws.amazon.com/about-aws/whats-new/2019/09/elastic-load-balancing-network-load-balancers-now-supports-multiple-tls-certificates-using-server-name-indication/