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
Redirect root to www
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.* 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.
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.
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.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).
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.