Use a Lambda Function to Send a Custom Host Header to an Origin from CloudFront

Wouter de Vos
Codaisseur Academy
Published in
4 min readJun 7, 2018

--

Let’s say you are in need of a tool to post vacancies and track applicants. So you found a nice SaaS tool, and it even allows you to set a custom domain. You decide to set it to jobs.mycompany.com.

Problem 1: No HTTPS

Now you got another problem. The SaaS tool no longer serves your
custom domain over SSL, so instead of https://jobs.mycompany.com, it serves from http://jobs.mycompany.com. Modern browsers do not like it, search engines also seem to favour HTTPS over HTTP, and what is worse: some browsers give nasty warnings when applicants want to fill in the application form. :(

Problem 2: Hostname Mismatch

To solve this issue, you can set up a CloudFront distribution to set up an HTTPS proxy.

Set the SaaS domain to mycompany.saas.com and proxy jobs.mycompany.com to cname.saas.com. This should work, but the the SaaS tool thinks it’s running on mycompany.saas.com still, and it might do weird things with redirects, or cause CORS errors (Access-Control-Allow-Origin errors) because the domain your browser is on does not match the hostname the SaaS tool expects.

Problem 3: SEO / Duplicate Content

If that is not a problem, there is still another problem: the SaaS tool is approachable through both mycompany.saas.com as well as through your custom jobs.mycompany.com domain. Search engines don’t like duplicate content, so it might be bad for SEO.

Solution: CloudFront + Lambda

In this article we will show you how to tackle these issues using a few AWS tools:

  • AWS Certificate Manager — (optional) to create the (free*) SSL certificate, but you can also use your own certificate
  • AWS CloudFront — to serve as an SSL proxy for the SaaS tool
  • AWS Lambda — to send a custom Host header to the SaaS tool
  • AWS Route 53 — (optional) to route your custom domain to CloudFront

*) You pay for traffic on the CloudFront distribution, but not for the SSL certificate itself.

Step 1 — Set the Custom Domain

Set your SaaS tool’s custom domain to whatever you want it to be, e.g. jobs.mycompany.com.

Step 2 — Create an SSL Certificate

Go to the AWS Certificate Manager and either 1) create an SSL certificate from scratch, or upload your own. Give it a name you recognize.

TIP: set up a wildcard certificate, e.g.: *.mycompany.com

Step 3 — Create a CloudFront Distribution

Go to CloudFront and set up a distribution:

Origin Domain Name: cname.saas.com (the CNAME target from your SaaS tool) and set the Origin Protocol Policy to HTTPS only.

NOTE: You might want to turn off CloudFront cache entirely, by setting Object Caching to “Customize” and all TTLs to “0”.

To make it work, you would have to set “Origin Custom Headers” to include a “Host” header with a value “jobs.mycompany.com”, but trying this will result in an error like:

“com.amazonaws.services.cloudfront.model.InvalidArgumentException: The parameter HeaderName : Host is not allowed.”

We will fix this by using a Lambda function.

Step 4 — Create a Lambda Function

When I ran into this issue, I found a rather cryptic post that eventually helped me set this up.

Go to AWS Lambda and make sure you are in the us-east-1 region (N. Virginia) as CloudFront requires Lambda functions it uses to be there.

Name your function (e.g. rewriteHostForMySaasTool), check that the Runtime is Node 6.10 and post in the following code:

Lambda function to force a specific Host header to be sent to the origin

Make sure to change jobs.mycompany.com to whatever your custom domain should be.

Then, at the top, click Actions > Publish new version and copy the ARN string including the version from the top of the screen (e.g. arn:aws:lambda:us-east-1:123456789:function:rewriteHostHeaderForMySaasTool:1)

Step 5 — Configure CloudFront Origin

Now go back to CloudFront and edit the Behavior’s settings.

Under “Lambda Function Associations” select “Origin Request” for the Event Type and paste in the Lambda Function ARN (including the version, it should end with “:1” or something).

Hit save and wait for the distribution to deploy.

Step 6— Configure You DNS

Now point your custom domain in your DNS to your CloudFront distro. If you use Route53, you can set up A and AAAA alias records that point to
xxxxxxxx.cloudfront.net otherwise you can set up a CNAME record that points to xxxxxxxx.cloudfront.net (check the actual cloudfront domain in your CloudFront panel — it’s probably not xxxxxxxx ;).

Now we wait!

Wait for technology to catch up with you (DNS cache, CloudFront deployment/update, etc.). When done, you should be good to go!

Hope this was useful. Let me know if you ran into any issues!

--

--

Serial entrepreneur in tech education. Founder of Kyna and Techmongers.