|
| 1 | +# Decision: DNS Management in Terraform |
| 2 | + |
| 3 | +> Status: Active |
| 4 | +
|
| 5 | +## Decision |
| 6 | + |
| 7 | +DNS records are managed in Terraform via the `kenske/technitium` provider. |
| 8 | +Two pieces, split deliberately: |
| 9 | + |
| 10 | +1. **`terraform/modules/dns-record/`** (this repo) — a thin reusable module |
| 11 | + wrapping the provider's `technitium_dns_zone_record`. Any Terraform root |
| 12 | + can compose it next to `module "proxmox-vm"`. |
| 13 | +2. **The `lan` primary zone** itself — created once and owned by |
| 14 | + `homelab-services/services/dns/terraform-config/`, never duplicated. |
| 15 | + |
| 16 | +The reusable `.github/workflows/provision-vm.yml` workflow accepts a |
| 17 | +`create_dns_record: bool` input. When `true`, it loads |
| 18 | +`/technitium/` from Infisical alongside `/proxmox/`, `/terraform/`, |
| 19 | +`/ansible/`, and forwards `TECHNITIUM_HOST` / `TECHNITIUM_TOKEN` to the |
| 20 | +Terraform apply step as `TF_VAR_technitium_*`. |
| 21 | + |
| 22 | +## Why composable, not integrated into `proxmox-vm` |
| 23 | + |
| 24 | +`proxmox-vm` callers aren't all the same. Some VMs are ephemeral |
| 25 | +(test runners, throwaway experiments) and shouldn't pollute the |
| 26 | +authoritative DNS zone. Some homelab installations may not have Technitium |
| 27 | +at all and would still want to use `proxmox-vm`. |
| 28 | + |
| 29 | +Integrating DNS into `proxmox-vm` would force every caller to either |
| 30 | +configure the `technitium` provider or special-case it with `count = 0` |
| 31 | +plumbing — friction for the common case. Keeping the modules separate |
| 32 | +lets callers opt in by writing two `module` blocks instead of one. |
| 33 | + |
| 34 | +The reusable workflow's `create_dns_record` flag is the matching |
| 35 | +opt-in at the CI layer: non-DNS callers don't need `/technitium/` access in |
| 36 | +Infisical. |
| 37 | + |
| 38 | +## Why the zone lives in `homelab-services`, not here |
| 39 | + |
| 40 | +The zone is a singleton — its SOA, refresh interval, allowed-update |
| 41 | +policy, and existence are all single-point-of-truth concerns. If two roots |
| 42 | +declared `technitium_dns_zone "primary"`, the second `terraform apply` |
| 43 | +would fight the first. |
| 44 | + |
| 45 | +`homelab-services` is the natural owner because the DNS *service* |
| 46 | +(Technitium itself) is deployed there. Records, on the other hand, live |
| 47 | +naturally with the thing they describe — the consumer's VM Terraform. |
| 48 | + |
| 49 | +## Why `kenske/technitium` |
| 50 | + |
| 51 | +Surveyed four community Technitium providers in May 2026: |
| 52 | + |
| 53 | +| Provider | Scope | Verdict | |
| 54 | +|----------|-------|---------| |
| 55 | +| `kenske/technitium` | zones, records, DHCP scopes, DHCP reservations | **chosen** — broad enough, room to grow into DHCP | |
| 56 | +| `kevynb/technitium` | records only (no zones) | too narrow | |
| 57 | +| `darkhonor/technitium` | zones, records, block lists, server settings, STIG mode | STIG opinions add overhead a homelab won't use | |
| 58 | +| `chinyongcy/technitium` | zones, records | smaller surface than kenske, similar feature set | |
| 59 | + |
| 60 | +Pinned to `~> 0.2.2` (latest as of Nov 2025). Single-maintainer risk is |
| 61 | +real; fallback if the provider goes unmaintained is direct API calls via |
| 62 | +`null_resource` + `local-exec curl` against |
| 63 | +[Technitium's HTTP API](https://github.com/TechnitiumSoftware/DnsServer/blob/master/APIDOCS.md). |
| 64 | + |
| 65 | +## Known gaps (managed in the UI for now) |
| 66 | + |
| 67 | +`kenske/technitium` v0.2.2 does not model: |
| 68 | + |
| 69 | +- **Forwarders / recursion settings** — Technitium's default (pure |
| 70 | + recursion to root servers) is what most homelabs want anyway. Set |
| 71 | + upstream forwarders via the UI if you need to. |
| 72 | +- **Block lists** — UI: DNS → Blocked Zones → Block Lists. |
| 73 | + |
| 74 | +Both change rarely. If they ever need code-management, the |
| 75 | +`null_resource` + Technitium API escape hatch is the path. |
| 76 | + |
| 77 | +## Bootstrap is one-time and manual |
| 78 | + |
| 79 | +Terraform cannot mint its own API token; a human must log in once to the |
| 80 | +Technitium UI to create the `terraform` user and generate a token. The |
| 81 | +runbook lives at |
| 82 | +[`homelab-services/services/dns/BOOTSTRAP.md`](https://github.com/BlakeHastings/homelab-services/blob/main/services/dns/BOOTSTRAP.md). |
0 commit comments