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:
The end result:
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:
- Create custom cache policy to whitelist headers and forward protocol information
- Create custom origin request policy to whitelist host headers
- Create new certificate for domain name associated with new CloudFront Disctribution (if necessary)
- Create new CloudFront origin using existing ALB as origin
- 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.