Forwarding, blocklist and dynamic DNS with Terraform
These resources control how DTM resolves names it is not authoritative for, plus the DNS blocklist and dynamic-update settings. See forwarders and stub zones for the concepts.
Default forwarder
Section titled “Default forwarder”dtm_default_forwarder (role: editor or admin) is a cluster-wide
singleton: where DTM sends queries that match no authoritative zone,
conditional forwarder, or stub zone.
resource "dtm_default_forwarder" "this" { upstreams = ["168.63.129.16"] enabled = true}Set enabled = false to answer non-matching queries with REFUSED instead of
forwarding them.
Conditional forwarders
Section titled “Conditional forwarders”dtm_forwarder (role: editor or admin) forwards one domain to specific
upstreams.
resource "dtm_forwarder" "ad" { domain = "corp.contoso.com." upstreams = ["10.0.0.1:53"] comment = "Active Directory DNS"}| Attribute | Required | Description |
|---|---|---|
domain |
Yes | FQDN with trailing dot. Changing it replaces the resource. |
upstreams |
Yes | Resolvers as ip:port or bare IP. |
comment |
No | Free-form note. |
enabled |
No | Defaults to true. |
Stub zones
Section titled “Stub zones”dtm_stub_zone (role: editor or admin) tracks a delegated domain’s
nameservers from a set of hints.
resource "dtm_stub_zone" "partner" { domain = "partner.local." hints = ["10.5.0.1:53"]}| Attribute | Required | Description |
|---|---|---|
domain |
Yes | FQDN with trailing dot. Changing it replaces the resource. |
hints |
Yes | Bootstrap nameserver IPs. |
comment |
No | Free-form note. |
enabled |
No | Defaults to true. |
refresh_interval_seconds |
No | How often to refresh the NS list (0 = server default). |
Blocklist
Section titled “Blocklist”dtm_blocklist (role: editor or admin) is a cluster-wide singleton that
sinks matching names to NXDOMAIN (suffix match).
resource "dtm_blocklist" "this" { domains = [ "doubleclick.net", "trackers.example", ]}The computed entry_count reports the deduplicated number of entries.
TSIG keys (dynamic updates)
Section titled “TSIG keys (dynamic updates)”dtm_tsig_key (role: editor or admin) authorises RFC 2136 dynamic
updates to specific zones. Every attribute forces replacement, so rotate by
creating a new key.
resource "dtm_tsig_key" "dhcp" { name = "dhcp-update." algorithm = "hmac-sha256" secret = var.tsig_secret # sensitive, base64, >=128 bits decoded zone_ids = [dtm_zone.example.id]
lifecycle { create_before_destroy = true }}| Attribute | Required | Description |
|---|---|---|
name |
Yes | Key name, e.g. dhcp-update. (trailing dot optional). Used as the API key. |
algorithm |
Yes | hmac-sha256 (recommended), hmac-sha384, or hmac-sha512. |
secret |
Yes | Base64 shared secret, at least 128 bits decoded. Sensitive. |
zone_ids |
Yes | IDs of the zones this key may update. |
When a signed dynamic update or zone transfer arrives, DTM matches the wire key
name against the stored name case-insensitively and with or without the
trailing dot. A key stored bare (the form nsupdate and dnssec-keygen use)
therefore authorises the same operations as its dotted equivalent.
Import a TSIG key by its name (not ID): terraform import dtm_tsig_key.dhcp dhcp-update.
Dynamic DNS and AXFR
Section titled “Dynamic DNS and AXFR”Both are admin singletons, with one scope difference: the AXFR record applies
live and replicates cluster-wide, while the dynamic-DNS record configures
only the node the provider’s endpoint targets, so declare one
dtm_dynamic_dns_config per provider endpoint for each node that should
accept RFC 2136 updates (see dynamic DNS).
# Enable RFC 2136 dynamic updates on the endpoint's node, requiring TSIG.resource "dtm_dynamic_dns_config" "this" { enabled = true require_tsig = true}
# Allow zone transfers (AXFR) from a CIDR, requiring TSIG, and send# RFC 1996 DNS NOTIFY to a mirroring secondary on every zone change.resource "dtm_axfr_config" "this" { enabled = true allowed_cidrs = ["10.0.0.0/8"] require_tsig = true
notify_targets = ["10.20.0.10:53"] notify_tsig_key_name = "mirror-key" notify_debounce_seconds = 5}The three notify_* attributes drive outbound DNS NOTIFY: each target gets
one NOTIFY per zone per quiet window (notify_debounce_seconds, so a bulk
import does not storm the mirror), optionally signed with a stored TSIG key
(a missing key fails closed rather than sending unsigned). Like the rest of
the record, they apply live and replicate cluster-wide.
Forwarder hardening
Section titled “Forwarder hardening”dtm_forwarder_hardening_config (role: admin, per-node singleton: it
hardens only the node the provider endpoint targets, like
dtm_dynamic_dns_config above; apply it via each node’s endpoint to cover the
cluster) constrains the default forwarder with an optional allowlist and
per-client rate cap.
resource "dtm_forwarder_hardening_config" "this" { qname_allowlist = ["microsoft.com.", "azure.net."] per_client_qps = 50 per_client_burst = 100}An empty qname_allowlist forwards everything; per_client_qps = 0 means no
per-client cap.