Point an Amazon CloudFront distribution to a load balancer origin

AWS ELB SLL Path

Recently I decided to add a CloudFront distribution in front of a public facing application load balancer and it turned out to be more complicated than I’d anticipated. I faced two issues: The first was that I was using an ALB as my origin instead of the more commonly used S3 bucket. The second was that I had an existing SSL certificate on an ALB that was configured to redirect incoming HTTP traffic to HTTPS and then send that traffic to a pool of IIS servers that were listening on port 80. Adding to the certificate situation was that the IIS pool uses host headers to differentiate incoming traffic across multiple web sites internally.

I started with this:

Amazon Application Load Balancer pointing to an IIS EC2 targer group
Traffic coming in from the internet is directed via Route53 to the Application Load Balancer. HTTP traffic is redirected to HTTPS which is protected by an AWS-issued certificate. The ALB then forwards traffic to an IIS target group that is listening on port 80. With this configuration, traffic is encrypted between a visitor and the ALB, and is in unencrypted from the ALB to the IIS servers.

The end result:

Traffic coming in from the internet is directed by Route53 to the CloudFront distribution, where HTTP traffic is redirected to HTTPS. If the cache is not hit, the request is forwarded over HTTPS to the ALB, which then forwards the request over HTTP to the IIS target group. With this configuration, traffic is still encrypted between a visitor, through CloudFront, to the ALB, and is unencrypted from the ALB and the IIS servers.

Where it gets complicated is that, by default, CloudFrontdoes not include the original header when forwarding a request to the ALB. And since my IIS servers were using host headers to differentiate traffic to various web applications, not having the proper header resulted in incoming traffic hitting the default web site in IIS which redirects to www.rainwalk.net. The solution is to create policies for CloudFront that forward header information along with the request. In addition, CloudFront will also cache 301 requests (redirects) so it is necessary to forward the CloudFront-Forwarded-Proto header to the origin.

The steps are:

  1. Create custom cache policy to whitelist headers and forward protocol information
  2. Create custom origin request policy to whitelist host headers
  3. Create new certificate for domain name associated with new CloudFront Disctribution (if necessary)
  4. Create new CloudFront origin using existing ALB as origin
  5. Change domain name record to point to new cloudfront distribution instead of ALB

Step 1 – Create Custom Cache Policy

The CloudFront distribution needs a custom cache policy to whitelist headers and forward protocol information. I created a caching policy called CachePolicy-ForwardHeaders that I will associate with my new distribution. This policy will add CloudFront-Forwarded-Proto and Host headers to requests passed through the distribution to the origin.

Step 2 – Create custom origin request policy

The CloudFront distribution needs a custom origin request policy to whitelist host headers information, allowing IIS to determin which web site is sending and receiving traffic. I created a policy called OriginRequestPolicy-Host Headers that I will associate with my new distribution.

Step 3 – Create SSL certificate

I’m not going to go into that here, but I needed to create an SSL certificate using the Amazon Certificate Authority that contained the name of the web site(s) that were to be hosted by this distribution. One gotcha is that certificates need to be created in us-east-1 to be visible to CloudFront.

Step 4 – Create new CloudFront distribution

I created a new CloudFront distribution, specifying the alternate domain names that would be served by this distribution. It is important that there exists a SSL certificate with a name that matches the alternate domain name of the new distribution for HTTPS traffic to flow properly.

I specified HTTPS only for the origin policy:

And then I specified cache behavior. I am redirecting all traffic to HTTPS (though I could have opted to let HTTP and HTTPS through since my ALB also redirects HTTP traffic to HTTPS. This seemed neater for some reason.

I also specified my custom cache and origin request policies to ensure that headers were handled appropriately.

And then finally I switch my DNS record for my web site, swinging traffic from the ALB to the CloudFront distribution.

Leave a Comment

Your email address will not be published. Required fields are marked *