Setting up all kinds of full-domain redirects in S3 and CloudFront

March 5, 2019 · Chris Peters

When redirecting an entire domain/subdomain, I've found S3 and CloudFront to be a nice toolset. For most use cases, AWS is cheap, easy, and reliable.

The longer a company has been on the web, the more likely that it has some history and cruft built up that needs to be cleaned and consolidated. I’ve killed quite a few extraneous domains and subdomains over the course of my career as a digital professional.

When removing an entire domain/subdomain and redirecting it, I’ve found Amazon Web Services S3 and CloudFront to be a nice toolset. For most use cases, AWS is cheap, easy, and reliable. Let’s look over how to do the most common redirection scenarios.

Why go through the trouble of setting up redirects in the first place?

If the domain you’re removing has any links pointing to it from your own website or other websites, setting up 301 redirects will help transfer that link authority to your main site. And users won’t run across bookmarks or broken links pointing to your old domain.

Are there any cases where you wouldn’t want to do this? I can think of a couple:

  1. You are 100% certain that there are no bookmarks, emails, or links pointing to the domain or subdomain you’re about to kill.
  2. Some disaster happened, and there are more toxic links pointing to your old domain than good links. (Seriously, I have run across this before with a previously-deleted forum site that was attacked with tons of spammy links.)

Why set this up on Amazon Web Services?

I think the main reasons to go with AWS is a common reason for most IaaS providers:

Before I started learning about S3 and CloudFront, I would solve this problem by adding some extra virtual hosts for the old domains to the Apache config on my main web server. As I’ve entered more situations where I don’t have a huge staff or any extra time, I’ve found this approach to be inconvenient when it’s time to get rid of that lone web server and migrate everything off of it.

Using AWS decouples the whole configuration dance of these redirect-only domains from any given web server and keeps all of the extra redirect-only domains away from your essential websites and web applications.

Setting up S3

There are 3 different full-site redirection scenarios I’ll cover below:

  1. To another domain, preserving path
  2. To a single page on another site
  3. To a specific path on another site, appending the source site’s path to the end

To another domain, preserving path

If you want to redirect an entire domain to another and preserve the path of the original URL, you’re in luck. This has been the most common scenario for me and by far the easiest to set up with S3 and CloudFront.

Example redirects in this scenario

  • www.example.com/ to www.example.org/
  • www.example.com/folder/page/ to www.example.org/folder/page/
  • www.example.com/page/?foo=bar to www.example.org/page/?foo=bar

How to set it up

First, set up a bucket in S3. For clarity, I usually just name it after the original domain that I’m redirecting, but it doesn’t matter all that much. In this example, the name of the bucket would be www.example.com.

Under the bucket’s Properties, enable Static website hosting. Then choose Redirect requests and enter the Target domain and Protocol.

S3 static website hosting, redirect

Easy as promised.

Later in this post is a section about hooking this up to CloudFront.

To a single page on another site

It’s fairly simple to set up a redirect that takes all of a domain’s pages and subpages and redirects them to the home page or a single specific path on another domain.

Example redirects in this scenario

  • www.example.com/ to www.example.org/
  • www.example.com/folder/page/ to www.example.org/
  • www.example.com/page/?foo=bar to www.example.org/

Or…

  • www.example.com/ to www.example.org/page/
  • www.example.com/folder/page/ to www.example.org/page/
  • www.example.com/page/?foo=bar to www.example.org/page/

How to set it up

First, set up a bucket in S3. For clarity, I usually just name it after the domain that I’m redirecting. Let’s say it’s www.example.com.

Under the bucket’s Properties, enable Static website hosting. In this case, you want to Use this bucket to host a website instead of “redirecting requests.”

Under Redirection rules, enter something like this:

<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals/>
</Condition>
<Redirect>
<Protocol>https</Protocol>
<HostName>www.example.org</HostName>
<ReplaceKeyWith></ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
view raw redirects.xml hosted with ❤ by GitHub

In this example, we’re redirecting everything on www.example.com to the home page of www.example.org.

S3 static website hosting with redirection rules

(If we wanted to redirect everything to www.example.org/test/, for example, we’d provide a value of test/ for ReplaceKeyWith.)

Later in this post is a section about hooking this up to CloudFront.

To a specific path on another site, appending the source site’s path to the end

If we want to translate a path on a source domain to the end of a path on another target domain, the setup is a bit more involved. It will require use of AWS’s Lambda@Edge service and a little bit of JavaScript code to run in a Node.js container.

Example redirects in this scenario

  • www.example.de/ to www.example.com/de/
  • www.example.de/folder/page/ to www.example.com/de/folder/page/
  • www.example.de/page/?foo=bar to www.example.com/de/page/?foo=bar

How to set it up

First, set up a bucket in S3. For clarity, I usually just name it after the original domain that I’m redirecting. In this example, the name would be www.example.de.

Under the bucket’s Properties, enable Static website hosting. Then choose Redirect requests and enter the Target domain and Protocol.

Later in this post is a section about hooking this up to CloudFront. Follow those steps and then return back here for the rest of the steps.

With the CloudFront endpoint setup, you can now create a new function in AWS Lambda. Hooking Lambda into CloudFront is only available in the Northern Virginia data center, so be sure to select that in the upper right before getting started.

I usually name the function in the format exampleDeSubfolderRedirect for our example of redirecting www.example.de.

Then in the code editor, we would author something like this:

'use strict';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
let uri = request.uri ? request.uri : '/';
if (request.querystring) {
uri += '?' + request.querystring;
}
const redirectTo = 'https://www.example.com/de' + uri;
callback(null, {
status: '301',
statusDescription: 'Moved Permanently',
headers: {
location: [{
key: 'Location',
value: redirectTo,
}]
}
});
};
view raw index.js hosted with ❤ by GitHub

The code is basically intercepting the request passed to the origin and appending it to the end of https://www.example.com/de, and signaling to the client that it should 301 redirect to the new URL. Just as we want.

Deploy to Lambda@Edge configuration

In the Designer section, we can hook this function up to a CloudFront trigger. In that dialog, you choose the Distribution you set up in CloudFront by ID, a CloudFront event of origin-request, and check the box next to Include body.

Setting up CloudFront to serve the redirections via its CDN

With redirection buckets set up in S3, it’s now time to use CloudFront to distribute the redirects across the content delivery network (CDN). The setup tends to be mostly the same, no matter the type of redirection that you’ve set up, hence why this section is split out from the other how-tos in this post.

The biggest gotcha to setting up a CloudFront endpoint for redirections is the Origin Domain Name field. When you move your cursor into the field, you get selections for the various S3 buckets in your account. They end up looking something like this: www.example.com.s3.amazonaws.com.

S3 website hosting endpoint URL

In our case, we instead want to get the HTTP endpoint URL for the bucket from its Static website hosting Properties. It will end up looking more like this: http://www.example.com.s3-website.us-east-2.amazonaws.com.

The Query String Forwarding and Caching field should also be set to Forward all, cache based on all if query strings need to be preserved across the redirect (for example, ?foo=bar at the end of the URL).

You’ll also need to provide the Alternate Domain Names (CNAMEs) that are being redirected: www.example.com and example.com for our example.

Lastly, if you need HTTPS for the redirected domain, AWS ACM is a great option for generating a free no-maintenance SSL/TLS certificate. It is automatically installed into your CloudFront distribution and renewed every 3 months without needing your involvement. Just choose Custom SSL Certificate, click Request or Import a Certificate with ACM, and get that all set up for your redirected domain. (Note that this likely will involve verification of your domain name through adding an extra DNS record or verifying receipt of an email. The DNS validation is most reliable but does take some extra time to set up.)

Unless you have any specific reasons to change them, the default values for the rest of the fields tend to be OK for most situations.

Set and forget your domain redirects

With this setup on AWS, configuring redirects for your old domains will not even make the to-do list the next time you redesign and/or re-platform your website. While there is some configuration up front, it truly is a “set it and forget it” affair. If you utilize ACM, you don’t even need to think about generating and installing new SSL certificates every year or two.

Now let’s go on and worry about more important problems to solve.

About Chris Peters

With over 20 years of experience, I help plan, execute, and optimize digital experiences.

Leave a comment