Redirects with AWS Route53, S3 and CloudFront

 •  AWS Cloud Serverless

Recently I had to change domains and subdomains for a project I have worked on a couple of years ago. Usually redirects are simple, but, sometimes, not that simple many of us would like them to be. Changing DNS service records may not be enough. We may need to create an S3 bucket and a Cloud Front distribution.

So this will be a short blog post, which describes a couple of scenarios with domain redirects on AWS.

What do we have

Imagine, we have a project hosted on AWS, we have a static content which goes through S3 + CloudFront, we have some API implemented with AWS API Gateway + Lambda, maybe some microservices running on top of ELB/ALB plus EC2 or ECS. Basically, something similar to what I have described here.
In addition to that, we have a relatively complex Route 53 hosted zone with 20+ records (A records, subdomains, email records, aliases, etc.).

Now, for whatever reason, we want to host part of the platform outside of AWS.

Redirect subdomain to an external hostname

Let's start with something very simple first. Our domain is example.com and we want to have blog.example.com let's say on Ghost. For this, we just need to create a CNAME blog.example.com with Alias 'No', which points to something like example.ghost.org.

Redirect root to www

If www.example.com is an alias to an internal AWS resource (not a CNAME like in the example above), then it's quite easy. We can just create an alias for root A record which points to www.example.com. If www.* is a CNAME to an external resource, then it's a bit more complicated.

Redirect root to an external hostname

What if we want our main domain example.com to be outside of AWS and keep AWS Route 53 as our main DNS service? Also, we want customers to always see our main domain in their browser.

Our www.example.com is a CNAME which points to a resource, which is outside of your AWS environment. Here is what we need to do to redirect root (as of today).

We need to create an S3 bucket with the name which matches our main domain name (example.com), then go to bucket properties and enable Static Website Hosting with a redirect option. We will be redirecting to www.example.com. After that, we can create A Record Set in Route53 for our root domain with an alias to our example.com S3 bucket. Still simple enough.

staticwbst

At this point, everything should be working except HTTPS https://example.com. To make https redirect work for the root domain we need to create a CloudFront distribution for our example.com bucket. After that, point our A Record on Route 53 to CloudFront distribution instead of the bucket and https will work. A couple of possible pitfalls in this step:

  • when we set up your CloudFront distribution, in the Origin Domain Name field we need to specify the Static Website Hosting endpoint (see the screenshot above) and not the bucket name: example.com.s3-website-us-east-1.amazonaws.com, not example.com.s3.amazonaws.com; this is very important
  • if you see an error like "This XML file does not appear to have any..." when you're trying to access Cloud Front distribution link, you probably set an Origin Domain Name incorrectly; you have to fix that as described above and create an invalidation to update CloudFront cache
  • we don't need to make our bucket public or create any bucket policies, because our distribution origin is not the bucket itself

So what we ended up with: root domain will redirect to www.example.com using CloudFront + S3. www.example.com is a CNAME record in Route 53, which points to whatever we need.

This is the simplest way I have found today to redirect your root domain if you don't want to move all your DNS records from Route53 to another DNS.

Dealing with taken bucket names

If you can't create a bucket with a name of your root domain, which shouldn't happen often, you can create a bucket with a name like redirect.example.com. Do the steps from above for that bucket and then create an alias in Route53, which points your root domain to redirect.example.com record. We can create an alias from root to redirect.example.com record because the latter is an alias to an AWS resource (CloudFront distribution).

Conclusion

To paraphrase great Warren Buffett: "Redirects are simple, but not easy". Hopefully, eventually AWS team will give us a way to achieve the above with one little Route 53 record and without S3 bucket and CloudFront distribution.