Empower Your DNS: Unlocking Efficiency with Terraform & Bind9

As part of my Home DNS Rebuild I decided to use Bind for DNS resolution and Terraform Cloud as an IaC Solution to manage DNS.

Using Terraform gives me a lot of options to automate the creation and deletion of DNS entries as part of my workflows and infrastructure lifecycles. With Terraform managing state does become a challenge and this is where Terraform Cloud comes in. For work we use a lot of Terraform Cloud and after the licencing changes in 2023 the option became available to use it for my own automation as well.

Setting up the Workspace and Repo

As part of the Bind9 deployment we added a TSIG key. This will be used by Terraform as a authentication token to the DNS Server allowing it to do dynamic updates.

I included the TSIG key as a variable on the Terraform Cloud Workspace

Under general the Execution mode is set to Custom and my OnPrem Agent selected

I also liked the workspace to the Github.com repo hosting the terraform files. My files are all in the root of the repo on the main branch.

Setting for the Workspace VCS integration:
– Auto Apply: Auto-Apply API, CLI & VCS runs
– VCS Triggers: Only trigger runs when files in specified paths change
– Syntax: Patterns – /*

These settings will allow the bind9 config to be update every time I update the Git Repo. Some of my provisioning workflows are very basic and I do not have the time to approve every little run.

Terraform Config in Repo

In the repo I have all the standard terraform files. Currently I am not using a module to create these entries so I create a file for each DNS Entry and then there is also a provider file.


variable "TSIG_KEY" {
  type      = string
  sensitive = true

terraform {
  required_providers {
    dns = {
      source  = "hashicorp/dns"
      version = "3.3.1"

provider "dns" {
  update {
    server        = ""
    key_name      = "tsig-key."
    key_algorithm = "hmac-sha256"
    key_secret    = var.TSIG_KEY

We only need to update the Primary Bind9 node as the Secondary will update from the Primary.
For every DNS entry I then have a file defining that entries A and PTR Record.


resource "dns_a_record_set" "AriaAutomation_a" {
    zone      = "my.zone."
    name      = "AriaAutomation"
    addresses = [
    ttl       = 300

resource "dns_ptr_record" "AriaAutomation_ptr" {
    zone   = "70.10.in-addr.arpa."
    name   = "52.13"
    ptr    = "AriaAutomation.my.zone."
    ttl    = 300

Now for every update to the Repository Terraform cloud will pick up the change and run it.

To delete a record, simply deleting the .tf file.

For future reworks I will probably create a module for this to make the code a bit more reusable but for now this is working better than I expected. In running this now for 6 months, the Incident Management team(Wife) did not raise a single alert.

Using Bind DNS with Terraform Cloud is a fairly easy way of getting a automated free and mostly opensource DNS solution.

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights