I’ve been busy doing a few things in the background, like -not- adding content and being quiet.

All jokes aside, I have been transferring my cloud-side configuration to Terraform. Until recently I was using DigitalOcean as my hosting platform, but in the face of rising costs (and a weak GBP, where DigitalOcean charges in USD) I spent a few days last month building out a Kubernetes cluster in my homelab.

I’ll go into more detail another time, but for now let’s stick with cloud-side config. Specifically, DNS is something that has to be handled externally (well not quite, but it takes a a glutton for punishment to run their own DNS server at home).

So, I’m using Cloudflare to host my DNS zone, because it comes with a few web protection bells and whistles. My first attempt was to write out individual records using the Cloudflare record, like this:

resource "cloudflare_record" "website" {
    name = "website"
    type = "A"
    proxied = false
    value = 80.90.10.20
    ttl = "600"
    zone_id = var.zone_id
}

Terraform resources can be defined very simply, like this: WYSIWYG (what you see is what you get). It makes an A record for website.sierrana.co.uk with a TTL of 600 seconds, and attaches it to the DNS zone via the zone_id variable. Every record is created this way, which takes up a lot of screen real-estate (virtual-estate?) and some duplication.

A much more efficient way to do this is using a Terraform module, which lets me define some defaults and variable handling.

I make a module with the file dns.tf in the folder cloudflare. There are some variables I have to define, and some of them have default values.

locals {
    name    = var.name
    type    = var.type
    proxied = var.proxied
    value   = var.value
    ttl     = var.ttl
    zone_id = var.zone_id
}
resource "cloudflare_record" "record" {
    name    = local.name
    type    = local.type
    proxied = local.proxied
    value   = local.value
    ttl     = local.ttl
    zone_id = local.zone_id
}

Back in my top-level main.tf I can now call the module and give it a very small amount of information and it will create a record with all the default values I chose.

module "www" {
    source = "./modules/cloudflare"
    name   = "website"
}

I can pass additional information in, and it will change the record creation values, but since most of my records are made this way, I can save some time and effort - and most of all, the satisfaction of making it work.