dnswiz
← Back

DNS and IPAM as code

Zones, records, GSLB failover, TLS, and IP address space are one Terraform provider, one API, and one CLI. On every plan. No automation add-on.

DNS and the addresses under it are infrastructure, and they deserve the same treatment as the rest of your infrastructure: a diff in a pull request, a history, and a rollback. The official doon-io/dnswiz provider covers the whole product, so the dashboard is for looking and the code is the source of truth.

A zone and its failover, in one apply

A zone, a health-checked pool, its backends, the monitor, and the record that points at the pool are all resources you commit together.

resource "dnswiz_zone" "acme" {
  name = "acme.com"
}

resource "dnswiz_pool" "api" {
  name             = "api-backends"
  selection_method = "weighted"
}

resource "dnswiz_pool_member" "api_us" {
  pool_id = dnswiz_pool.api.id
  target  = "203.0.113.10"
  weight  = 100
  enabled = true
}

resource "dnswiz_health_monitor" "api" {
  name     = "api-tcp-443"
  type     = "tcp"
  port     = 443
  interval = 30
}

resource "dnswiz_record" "api" {
  zone_id = dnswiz_zone.acme.id
  name    = "api"
  type    = "POOL"
  ttl     = 60
  pool_id = dnswiz_pool.api.id
}

That is a complete failover setup for api.acme.com, expressed in a file you can read in review. The same provider covers ordinary A, AAAA, CNAME, MX, TXT, SRV, CAA and ANAME records, GEO and CANARY routing, zone policies, notification channels, and TLS certificates issued through DNS-01.

Your IP space, in the same workflow

Blocks organize themselves by CIDR containment, and networks place three ways: an explicit CIDR, the next free subnet in a block, or the next free subnet from any block carrying a tag.

resource "dnswiz_ipam_block" "corp" {
  cidr   = "10.0.0.0/8"
  name   = "corp"
  origin = "rfc1918"
}

# Next free /24 from ANY block tagged region:eu-central-1.
resource "dnswiz_ipam_network" "eu" {
  parent_tags   = ["region:eu-central-1"]
  prefix_length = 24
  name          = "eu-app"
  tags          = ["env:prod", "team:platform"]
}

# Next free host in that network.
resource "dnswiz_ipam_ip_address" "vip" {
  network_id = dnswiz_ipam_network.eu.id
  hostname   = "vip"
}

No more scrolling a spreadsheet for a free range. Ask for a prefix length and get one, locked per block so two applies never collide. Full walk-through in the IPAM as code post.

Allocate an address, get the record

This is the part no DNS provider and no standalone IPAM can do. Point a network at a DNS zone (a one-time link in the console or over the API), and every address you declare with a hostname publishes its own A or AAAA record into that zone. The address and the record stop being two systems you sync by hand, because they are one account and one apply.

One provider, and no upsell for it

  • Reviewed before it ships. A DNS or IP change is a diff in a pull request. terraform plan shows what will change before it is live.
  • Real drift detection. Plan compares what dnswiz is actually serving, not what a registry thinks it ought to be, so a hand-edit during an incident does not silently become the truth.
  • One source of truth. Zones, records, GSLB, monitors, policies, channels, TLS, and IPAM are one provider, so there is no second cert issuer to wire up and no separate IPAM to keep in sync.
  • Not gated. The API and the provider are on every plan, including Free. Programmatic access to your own DNS is not a monthly add-on.
Wire it into your stack
The provider is free to use and on every plan.

More: Terraform docs, IPAM docs, DNS as code, IPAM as code.