Skip to content

Instantly share code, notes, and snippets.

@tforster
Last active January 27, 2022 00:01
Show Gist options
  • Save tforster/f8c33db5149ce693d1d670dbb3980a54 to your computer and use it in GitHub Desktop.
Save tforster/f8c33db5149ce693d1d670dbb3980a54 to your computer and use it in GitHub Desktop.
Lambda@Edge function to redirect requests for a naked domain to the www subdomain

Naked Redirector Lambda@Edge Function

THIS GIST HAS BEEN DEPRECATED

AWS introduced CloudFront Functions as an alternative (but not replacement) to Lambda@Edge functions. Both have their pros and cons but for naked-domain-to-www redirection a CloudFront Function is a better choice. Please see Naked Redirector CloudFront Function for an implementation example.

Intended to run on CloudFront as Lambda@Edge, naked redirector checks the incoming hostname and if it is naked, e.g. somedomain.com and not www.somedomain.com, it will redirect to the www subdomain with preserved path and query string variables.

Table of Content

Install Dependencies for This Service

There are no dependencies for this service

Configure AWS Certificate Manager (ACM)

  1. Create a certificate in us-east-1 for somedomain.com and include *.somedomain.com as an additional domain. This certificate will not only cover somedomain.com and www.somedomain.com but any other subdomains you may wish to add later.

Deploy This Service

  1. Open the AWS Lambda console. Ensure the region is set to us-east-1 as AWS does not support @Edge functions in other regions.
  2. Create a new function
  3. Copy and paste the contents of index.js from this gist to the new function
  4. Edit the domain placeholders with your own
  5. See the following note regarding IAM role trust policy

Configure CloudFront

  1. Create the distro
  2. Add www.somedomain.com and somedomain.com as CNAMEs
  3. Select the new ACM certificate
  4. Navigate to the behaviour tab and add a new "viewer request" Lambda@Edge function specifying the ARN for the one you created above.

Configure Route53

  1. Create an A record for www.somedomain.com that is an alias to the CloudFront distribution
  2. Create an A record for somedomain.com that is an alias to the CloudFront distribution

Useful Information

This is a very trivial, albeit extremely useful, Lambda@Edge function. It is triggered by CloudFront for every viewer request made. It simply checks the incoming hostname to ensure it is referencing the www subdomain (e.g. www.somedomain.com) and lets the request continue on to be handled by CloudFront normally. If the hostname happens to be the naked domain (e.g. somedomain.com) then the request is 301 redirected to https://www.somedomain.com. As an added bonus, it redirects for both http and https as it does not check the protocol for naked domains.

One minor "gotcha" to be aware of is that @Edge Lambda functions require some additional permissions beyond typical AWS FaaS, namely lambda.amazonaws.com and edgelambda.amazonaws.com. This Lambda@Edge is currently configured to use a custom IAM role nakedRedirectorRole whose trust relationship policy document looks like:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": ["lambda.amazonaws.com", "edgelambda.amazonaws.com"]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
("use strict");
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
if (request.headers.host[0].value === "{naked-domain}.com") {
return {
status: "301",
statusDescription: "Redirecting to www subdomain.",
headers: {
location: [
{
key: "Location",
value: `https://www.{naked-domain}.com${request.uri}`,
},
],
},
};
}
return request;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment