One of the things that I find most surprising about AWS’s Free Tier, is that it doesn’t include Route 53.

I mean, you get a very ample amout of DynamoDB storage (25GB), a million Lambda requests a month - always free.. And 12 months of free EC2 micro instance, and RDS – enough to build out a small project or home lab without incurring fees (Be careful, though, and always set up billing alerts.). But not to offer any free tier for Route 53 seems rather odd, a web service without DNS is kinda anaemic.

Cloudflare, on the other hand, offer a really nice free DNS service - with a nice API to interact with it. An API that’s well supported by Terraform. A lot of the things I build in my spare time have are fronted by Cloudflare, and pretty much every domain I own uses their DNS. Including this one.

So on Saturday afternoon, I thought I’d have a play around with terraforming a Cloudfront CDN to front a S3 bucket, but to use Cloudflare’s DNS instead of Route 53.

The Plan:

  • Create a S3 bucket in eu-west-1
  • Create an ACM Certificate for cdn.wibblesplat.com in us-east-1 (ACM certificates for Cloudfront need to live in us-east-1)
  • Create the ACM Domain Validation records in Cloudflare’s zonefile for wibblesplat.com
  • Create a Cloudfront Distribution for cdn.wibblesplat.com using the ACM cert, and origin of the S3 bucket.
  • Add a CNAME (with no proxying) to point cdn.wibblesplat.com at the distribution domain name from Cloudfront.

My code for this solution is here

You’ll need to set up a Cloudflare API Token with Edit Zone permissions for your selected zone, or else you get this error:

╷
│ Error: no zone found
│ 
│   with data.cloudflare_zone.primary,
│   on cloudflare_data.tf line 1, in data "cloudflare_zone" "primary":
│    1: data "cloudflare_zone" "primary" {
│ 
╵

I haven’t actually tested this with Cloudflare in Proxy mode, because two layers of CDN seems ridiculous - as if Cache Invalidation wasn’t a hard enough problem already. So really it’s just using Cloudflare for DNS - and would work equally well with any other Terraformable DNS provider.

My main reason for doing it this way, rather than having S3 in ‘static website mode’ is that I still, to this day struggle to get the fine balance of ACL controls and permissions correct. Doing it this way with Cloudfront and an OAI means at least I can leave the bucket private, and also have more control in future, if I want to do anything with Lambda@Edge, for example.

If anyone from AWS happens to read this, It’d be lovely if the Free Tier included one public hosted zone on Route 53.