Using CloudFlare to Validate DNS For An ACM Certificate

I recently received a notification from AWS indicating that ACM certificates I had in place for some S3 buckets I expose for websites could not renew due to an inability to validate via DNS.

Figuring out how to make it work was non-trivial, so I'm writing it up so I can remember in the future, and maybe save somebody else some trouble, as everything I found had to do with auto-provisioning via Terraform.

The problem

When you get certificates via ACM, you can validate them via email or DNS, with DNS validation being preferred. Each certificate provides a CNAME record for verification purposes that you need to register with your DNS provider, if you're not using Route 53.

I use CloudFlare.

Some background on my DNS situation

This was an interesting situation this year, because I migrated my DNS twice in around 12 months. I'd been using FreeDNS from afraid.org for, well, decades. However, I discovered that my domain was being flagged for spam, and when I investigated, I discovered that FreeDNS was allowing people to register on subdomains of my domains.

You really truly get what you pay for.

I switched to a commercial provider, in part to disassociate my domains with the spam subdomains, and this worked brilliantly, until it didn't. Less than a year in, I discovered one day that my sites and email were inaccessible because the DNS was unavailable. And this was due to having had somebody initiate a DNS flood against my domain, which used up the allotted requests I had in a given month. When I reached out to them, they pointed to their business and enterprise tiers, which protect against DNS floods, and I noped out, as the prices were too high for a hobbyist/individual like myself.

So I ended up at CloudFlare, who will host DNS for free AND protect against DNS floods by default.

And somewhere along the way, I evidently didn't migrate over my DNS records for the S3 buckets, which is why this all became so difficult.

How to make it work

When you export DNS records from ACM to use for validation, they are in a CSV file that looks like this:

Domain name,CNAME name,Type,CNAME value
subdomain.example.org,_somelonghashhere.subdomain.example.org.,CNAME,_somedifferenthashhere.acm-validations.aws.

The problem I ran into when I went to CloudFlare with this is that a CNAME record consists of two pieces: the alias, and the target. This CSV had three pieces of information (domain name, CNAME name, and CNAME value).

So what I had to do was the following:

  • I needed to create a CNAME record pointing the subdomain to the public DNS name for the S3 bucket. To do this, I needed to get that DNS name from the S3 bucket via the AWS console. The subdomain becomes the alias, and the S3 bucket becomes the target.
  • After doing this, I could create an additional CNAME record from the ACM export that used the CNAME name and CNAME value fields as the alias and target. One important thing I discovered here was that I should NOT provide the trailing . in each value.

After doing this for each subdomain I map to an S3 bucket, I received a notification from ACM within the hour indicating my certificates had renewed.