Dynamic DNS Updates with Terraform
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
.
Related posts:
Wanting to leave a comment?
Comments and feedback are welcome by email (aaron@nospam-aaronsplace.co.uk).