Managing DNS (or any other infrastructure) using Terraform

Note: This post ended up being a lot longer than I expected it to be! It’s a post about why Terraform is great, even for setups where configurations don’t change often and how you can use it to share the access that you have with other people without giving them access to the actual infrastructure account. I will make a separate post about the specifics of importing DNS records from Cloudflare into Terraform and the process I used for that.

Terraform is great! It is a way to manage your infrastructure using a set of version-controlled text files with a plan command that tells you what is going to change and an apply command that applies the changes that the plan told you about.

Where terraform gets really good is when you store the Terraform State file in a GCS bucket and run the plan and apply commands in your repository’s CI.

It’s a loot of hoopla for DNS management of a personal domain. Is it worth it? Well, that depends on whether you have the time and motivation to set it up. Once you set it up though, it’s INCREDIBLY convenient.


Terraform has three concepts that are pretty useful to know about:

So, in this manner, terraform has completed abstracted out the actual infrastructure being managed from the provider that it is provided by. Everything is a resource in the terraform world, and there can be only three operations to a resource: create, update or delete.

How useful is it?

Now, just having a log of all the changes you have made to your DNS records is pretty useful. You can go back and forth in time, you will never really have to deal with IPs again because of how easy it would be to create a new record, and so on.

The other features that terraform brings to the table are:

Both the first and second are extremely useful for DNS management. I use Cloudfare as the DNS provider for my personal domain, and cloudfare has this annoying way of changing DNS credentials from one account to another account. You have to export the DNS records, import it into the new account and then change the NS records at the domain provider.

I tried to do that once for (another domain that my account is connected to) and it did not go well. Something went wrong, the transfer didn’t work and the website was down for about 12 hours. This wasn’t very catastrophic, it’s a college project and it went down at a time when very few people were trying to access the domain. Nevertheless, the whole point of that was to ensure that the DNS was being managed by someone who was in the college instead of someone who had graduated.

The thing about colleges is that people keep graduating! And few people in their freshman or sophomore year have any clue about what DNS is or what records are or how to change them safely etc. I learnt most of the things I know about DNS in my fourth year at college. So, this would be a perennial problem.

So, the basic thing that I was looking for from a move to terraform was a way to safely share access to the infrastructure provider with other people.

A completely local setup

Now, you can have a bunch of terraform configuration files in a repository alongwith the state file. You can run appropriate terraform plan and terraform apply commands manually. The state file is a file that has to be maintained separately from the configuration files.

One way to do it that’s fairly manual and works for use-cases where changes are not very common and are centralized with a few people is to keep the state file checked into Git. The state file is a JSON file and can be easily stored and versioned. The local flow would look something like this:

This is already a great improvement on the nightmarish process of moving DNS management from account to account just to let others take over access. You have to remain involved in the process, yes, but at least others can review and all you have to do is run the plan and apply commands.

What if you use Continuous Integration?

Continuous Integration (CI) makes this whole process incredibly easy. It de-centralizes DNS management without de-centralizing control over the provider account. Here’s the flow with CI:

This is the holy grail. A single repository on which users can be added and removed as required.