How to use a custom domain on CloudFront with Cloudflare-managed DNS
How AWS and Cloudflare can work together to host a webapp on your own domain
Using a custom domain with a hosting provider seems like an easy thing to configure, but somehow it usually gets a lot more complicated. In this article you'll learn how to configure a CloudFront distribution to use a domain managed by Cloudflare and what are the important points along the way.
Setup
This solution is based on a fairly staightforward setup. The domain is registered on Cloudflare and it is its name server. Then the site itself is hosted in a CloudFront distribution that provides access to AWS's global delivery network.
When you create a CloudFront distribution by default it provides a URL that is under the cloudfront.net
domain:
This hosts the site under a randomly generated URL:
While CloudFront by default provides a certificate and a publicly accessible endpoint, it's not suited for user-facing websites. Fortunately, it's possible to host the same distribution under a domain you own with full HTTPS support.
To make this work, you'll need a certificate registered in AWS Certificate Manager (ACM). Then you can add the certificate and the custom domain to the distribution. Finally, the DNS needs to point to the CloudFront URL so that when visitors are coming to the site they go to CloudFront.
Let's see these steps!
ACM certificate
A certificate is needed not only to provide HTTPS support but for CloudFront to allow adding the custom domain. Public certificates are free to request and use.
The certificate for CloudFront must be in the us-east-1 region, and it doesn't matter in what region the distribution is created. Make sure to change to us-east-1 when you request the certificate.
During the process, you need to enter the domain first:
Then you need to verify that you own the domain. Certificates are powerful things and it's a major breach if an attacker can get one.
You can choose between DNS and email validation. The former is done by adding a CNAME record to the domain. This is the preferred way as as long as the record is in place AWS can refresh the certificate.
Email-based validation sends an email with a link to manually verify ownership. This proves that you have access to the email addresses that are associated
with the domain's managers, such as hostmaster@domain
. The downside of email validation is that it is a point-in-time proof and you need to manually reverify
it from time-to-time.
With DNS validation, ACM provides the validation record's name and value:
Go to the domain provider, in this case it's Cloudflare, and add the record. Make sure that it is only used for DNS resolution only and is not proxied.
After some time the validation happens and the certificate's status becomes "Issued":
CloudFront custom domain
With the ACM certificate in place go back and configure the CloudFront distribution. Add the domain name to the Alternate Domain Names box, then select Custom SSL Certificate then the certificate.
By using a custom domain, CloudFront offers dedicated IP addresses for "legacy clients" for a hefty price. Make sure to not use this, there are no clients out there who need dedicated IPs.
Cloudflare CNAME config
The final step is to point the domain to the CloudFront distribution's URL. To do this, add another CNAME record, this time to the root with value of the distribution's domain. Make sure that you don't use proxying.
This seems like a trivial thing, but there are many things going on why it's possible. By the DNS standard, CNAME records can not be used for the root
of the domain (example.com
) only to subdomains (www.example.com
). But in the case of Cloudflare, it
support CNAME flattening which makes it possible to add this CNAME record.
Another complication is that Cloudflare does not support NS records on the root, so you can not make another nameserver manage this domain. You can't just add a Route53 Hosted Zone and let that resolve the CloudFront distribution's domain.
But these problems only affect the root domain (example.com
) and not subdomains. It is perfectly fine to add a CNAME to a subdomain, such
as www.example.com
.
And why not use proxying?
CloudFront already provides a global distribution network, so there is not much benefit in routing all traffic through Cloudflare's network too. And it might bring complications down the road.
Result
With all these setup, opening the custom domain in the browser shows that it works:
It might take some time for the DNS to update everywhere, but it should happen eventually. It usually helps to clear the browser's DNS cache. In chrome, go
to chrome://net-internals
, select DNS, then click on the "Clear host cache" button.
Inspecting the certificate, the "Issued By" block shows that it is from Amazon:
Now you have a CloudFront distribution on a custom domain.