Blog IndexPosts by TagHome

Dynamic DNS Updates with Terraform

Posted <2021-08-15 Sun 18:48> by Aaron S. Jackson.

I've been playing around with some Hashicorp products lately. Namely Packer and Terraform. They both work very nicely with my home Proxmox box. Something I always found very annoying when "spinning up" test VMs at home was provisioning a hostname to go with it.

I'm very fussy when it comes to hostnames on my home network. Everything has a hostname, even if it's just dhcp-x-xx.nat.rhwyd.co.uk. I did a ran a quick Google search and found that Terraform supports RFC2136 DNS updates, but I'd never configured my name servers to do this before. Essentially, RFC2136 specifies that DNS updates can happen remotely, either unauthenticated, or authenticated. Within ISC named, this authentication can be performed either by the remote's IP address (not very good authentication), or by a pre-shared key, such as hmac-sha512 or RSA SHA1 (which is the default). I recommend using a separate zone for these updates, since these dynamic updates will destroy your carefully handcrafted zone files.

Generating such a key (for dyn.rhwyd.co.uk. zone) is as simple as running:

tsig-keygen -a HMAC-SHA512 dyn.rhwyd.co.uk.

The output of this can be added or included to your named config. Within the zone specification on your name server, you can add an update policy. The one below says, using the key dyn.rhwyd.co.uk, allow the creation of subdomains within dyn.rhwyd.co.uk of types A and SRV. You can also allow types such as AAAA or CNAME, if you want.

update-policy { grant dyn.rhwyd.co.uk. subdomain dyn.rhwyd.co.uk. A SRV; };

Next, we want to modify our Terraform script to update the zone. The nice thing about this is that it will also take care of destroying the entry when you tare down your stack. The following script will create a host record for you. I export the variable TF_VAR_dns_secret instead of hard coding the value within my script.

terraform {
  required_providers {
    dns = {
      source = "hashicorp/dns"
      version = "3.2.1"
    }
  }
}

variable "dns_secret" {
  type = string
}

provider "dns" {
  update {
    server        = "vinci.rhwyd.co.uk"
    key_name      = "dyn.rhwyd.co.uk."
    key_algorithm = "hmac-sha512"
    key_secret    = var.dns_secret
  }
}
resource "dns_a_record_set" "a-dns-entry" {
  zone = "dyn.rhwyd.co.uk."
  name = "test-record"
  addresses = [
    127.0.0.1
  ]
  ttl = 300
}

And that's it! You'll want to run terraform init, and then you can apply it using terraform apply.

Wanting to leave a comment?

Comments and feedback are welcome by email (aaron@nospam-aaronsplace.co.uk).

Related posts:

Tags: computing

Blog IndexPosts by TagHome

Copyright 2007-2021 Aaron S. Jackson (compiled: Sun 15 Aug 19:21:02 BST 2021)