Skip to content

3.6 Migrating to SpatiumDDI

Part 3 · Architecture & operationsArchitect⏱ ~30 min✓ Knowledge check

Migrations rarely fail at the import. They fail at the switch: a record nobody knew about, a lease handed out twice, an Active Directory domain that stops registering itself. SpatiumDDI’s migration tools follow one doctrine (import, observe, prove, cut over), applied one zone or one scope at a time, so every step can be undone until the last one. This module maps the tools to that doctrine, then walks through a sample Windows-to-SpatiumDDI plan for Ridgeline.

  • Apply import, observe, prove, cut over, one zone or scope at a time
  • Choose the right importer and use preview and commit safely, including re-runs
  • Keep SpatiumDDI from writing to production while you observe
  • Run a Windows cutover: parity, parallel run, TTL pre-flight, lease handover, the switch, rollback and decommission
Phase The question it answers SpatiumDDI tools
Import Is everything here? Importers with preview and commit, savepoints and provenance
Observe Does it stay right while production keeps changing? Read-only registration, lease sync, query logging, drift reports
Prove Do both sides give the same answers? Parity reports, shadow queries, readiness blockers
Cut over Can we switch, and switch back? TTL pre-flight, lease handover, per-item switch and rollback, decommission checklist, runbook

The unit of work is the zone or the scope. In a cutover plan every item moves on its own day and rolls back on its own; there’s no big-bang step anywhere.

You don’t have to hand SpatiumDDI control of anything on day one. The Getting Started guide’s lowest-risk trial is IPAM-only: make SpatiumDDI the source of truth for spaces, blocks, subnets and allocations while your existing DNS and DHCP servers keep serving. If you run Windows DHCP, register it read-only so live leases mirror into IPAM, with no write path to production. Then enable writes one subnet or one zone at a time. SpatiumDDI is beta, so in front of business-critical DHCP, pin a tested release and snapshot PostgreSQL before upgrades.

Importer Sources Lands in Feature module
DNS BIND9 archive (named.conf plus zone files); live pulls from Windows DNS, PowerDNS, Technitium and cloud DNS A DNS server group, optionally in a view dns.import
DHCP Kea JSON file; live pull from Windows DHCP (IPv4); ISC dhcpd.conf A DHCP server group, each scope linked to an IPAM subnet dhcp.import
IPAM Live pull from NetBox (v3.x to 4.6+) Spaces, blocks, subnets and addresses, plus VRFs, VLANs, customers and sites ipam.import.netbox

All three are superadmin-only, live on the Import page under Administration → Configuration, and behave the same way:

  • Preview parses the source and shows the plan with per-object conflicts. It writes nothing, so re-run it as often as you like.
  • Commit replays the plan you reviewed. Each object commits in its own savepoint, so object 50 failing doesn’t roll back objects 1 to 49, and a result ledger lists every attempt.
  • A didn’t import panel lists what isn’t translated: DNSSEC keys (re-sign after import), Kea hook libraries, ISC failover and TSIG keys, and classifier expressions. Live leases are never imported; they come from the real servers once those serve.
  • Some things are skipped rather than imported broken, each named in the preview’s warnings: a CNAME that sits beside other data or at the apex (#2089) and, from a BIND9 archive, zones that aren’t class IN; hint, mirror, redirect, static-stub and delegation-only zones; unquoted zone names; and included files.
  • Every created row is stamped with import_source and imported_at. A re-run defaults each conflict to skip, so committing twice never duplicates anything; pick overwrite (or, for DNS, rename) on purpose. Rows you created by hand never look imported, so an importer never claims them.
  • Connection secrets for PowerDNS, Technitium and NetBox are read once and never stored. Give NetBox a read-only token.

BIND9, PowerDNS and Technitium imports also carry the source server’s apex NS records, which would keep each zone delegated to the server you’re about to retire. The preview lists those per zone, and the review step offers an unticked Replace them with the target group’s servers box (#1892). It adds only group servers whose host is a DNS hostname (not an IP address or a single label). With none, the imported NS rows stay, with a warning, so repoint them yourself before you decommission the old server.

A DHCP scope must bind to an IPAM subnet. The commit links it to a subnet with the same CIDR, or creates one under the IP space and block you choose; leave those blank for link-only mode, which reports unmatched scopes instead of creating subnets. NetBox asks one design question up front: one IP space per VRF (per_vrf, the default), or everything in a single space (single).

Observing means SpatiumDDI watches production without changing it:

  • Register Windows DHCP read-only (a DHCP Users account) and enable DHCP Lease Sync, so live leases mirror into IPAM.
  • Turn on query logging for the target BIND9 group early. The parallel run replays names clients actually asked, taken from the last 24 hours of that log.
  • Watch drift. The zone’s Drift tab compares what each server serves with the database, and never changes anything.

Parity proves the configurations agree; the parallel run proves the answers do. Both run per item, on demand, inside a cutover plan (Import → Windows cutover).

That plan, and the cutover steps after it, live behind the Windows cutover module (migration.cutover), which ships off on a fresh install while the three importers stay on (#1069). Turn it on under Features & Integrations (group Tools) before you create a plan, and off again when the migration is done.

Parity diffs the live Windows server against SpatiumDDI and classifies every difference by why it exists:

Result Meaning What to do
in_sync Same on both sides (counted, not listed) Nothing
value_mismatch Same name and type, different data Decide which side is right
drifted_since_import Windows has it; the SpatiumDDI copy came from an import and Windows moved on Re-import it or add it here
never_imported Windows has it; it was never brought across Bring it across
intentionally_diverged SpatiumDDI has it; Windows doesn’t Usually an addition made here; it goes live at cutover

Two more states keep the report honest: not_compared counts records the Windows reader can’t see (for example CAA or TLSA over WinRM), and unverified marks an empty pull while SpatiumDDI holds records. That counts as never checked, which is a hard block.

The parallel run replays a sample of real questions (1 to 200, 25 by default) at the Windows server and at every server in the target group, with recursion off, and compares the answer sets. It’s for DNS items only.

Readiness blockers gate every switch. A warn needs an explicit acknowledgement; a block can never be forced. They’re re-checked against the live source at the moment you switch, not read from an old report. The one that matters most is ad_secure_dynamic_update: an AD zone set to Secure only accepts registrations only over GSS-TSIG, which SpatiumDDI doesn’t implement. Serving it from SpatiumDDI would silently stop domain controllers and clients from registering. Change the zone to Nonsecure and secure on Windows, or leave that zone on Windows.

  1. Lower the TTLs well before the window (DNS). The pre-flight snapshots the zone’s SOA values and every record’s TTL, then lowers them to a target (300 s by default, anywhere from 30 to 86,400). SpatiumDDI won’t write to the live Windows zone, so it gives you a PowerShell block to run there; a TTL drop on only one side buys nothing. Do it at least one current TTL before the window. Restore puts every value back exactly.
  2. Hand over the leases (DHCP). When Kea starts answering, its lease database is empty. The handover reads the live Windows leases and turns each into a reservation on the managed scope, so a renewing client keeps its address. Conflicts are never overwritten; you resolve them by hand.
  3. Switch. For DHCP, SpatiumDDI deactivates the Windows scope, then activates the managed one. For DNS there’s nothing to flip inside SpatiumDDI: it records the step and gives you the instructions (repoint the delegation, conditional forwarders and stub zones, and update DHCP option 6), leaving the Windows zone serving as the fallback.
  4. Roll back if you need to. Rollback is per item and deliberately skips the readiness checks. DHCP reverses the switch; DNS restores the TTL snapshot and gives you the revert instructions. Both directions report recovery_estimate_seconds: the zone’s TTL, or the scope’s lease time.
  5. Decommission. A 15-item checklist covers what bites weeks later: scavenging on the old DNS server, a DHCP server still authorized in AD, a forgotten conditional forwarder, DC SRV records, reverse-zone ownership and zone-transfer ACLs. Three items are evaluated for you, but none is ever ticked for you.

The plan’s runbook renders all of this as markdown for your change ticket, including the Windows-side PowerShell SpatiumDDI deliberately doesn’t run for you.

A sample plan: Ridgeline moves off Windows

Section titled “A sample plan: Ridgeline moves off Windows”

Suppose Ridgeline had started on Windows Server: corp.example.edu and its reverse zone 21.20.10.in-addr.arpa live on a domain controller, and Staff VLAN 21 (10.20.21.0/24) is a scope on a Windows DHCP server. The targets are the default DNS group (BIND9, dns-bind9) and the default DHCP group (Kea, dhcp-kea).

When Phase Action Done when
Week 1 Import Register the DC as windows_dns (Path B, a DnsAdmins account) and the DHCP server as windows_dhcp (a DHCP Users account), each in a group of its own; if the DHCP server has a failover partner, register both in that group. Import both zones into default, and the Staff VLAN 21 scope into default, linked to 10.20.21.0/24 in Campus. Clean commit ledgers; the didn’t-import panel reviewed
Weeks 1 to 3 Observe Enable DHCP Lease Sync and query logging on default. Keep dns_pull_from_server_enabled off, and make no edits in the Windows groups. IPAM shows live leases in 10.20.21.0/24
Week 3 Prove Turn on the Windows cutover module, create a cutover plan, discover its items, re-run parity until every difference is explained, run the parallel run, and clear blockers. Check each zone’s dynamic-update mode first. No block blockers; mismatches signed off
Day before TTL pre-flight Commit a 300-second target on both zones and run the PowerShell block on the DC. TTLs lowered on both sides, at least one old TTL before the window
Window Switch DHCP Commit the lease handover (cam-01 came across with the import, so it’s skipped), then cut over the Staff VLAN 21 item. Clients renew from dhcp-kea
Window Switch DNS Cut over each zone item, then repoint the delegation, forwarders and option 6 as instructed. dig against dns-bind9 matches, and so does a fresh parallel run
Weeks after Decommission Work through the checklist. Stop the Windows services rather than uninstalling them. Every item ticked by a person

Three practical notes. The switch deactivates the Windows scope over WinRM, which is a write, so by the window the read-only DHCP Users account isn’t enough: per-object writes need DHCP Administrators, which also avoids a denied read of the failover relationships. The decommission checklist includes that failover relationship. And the lease handover only covers leases inside the managed scope’s subnet.

Knowledge check · 6 questions

Migrating to SpatiumDDI

1. What does the Getting Started guide recommend as the lowest-risk way to start?

2. You accidentally commit the same NetBox import twice. What happens?

3. Why keep dns_pull_from_server_enabled off while you observe a Windows DNS server that is still in production?

4. A zone's parity report comes back unverified. What does that mean for the cutover?

5. A Windows zone uses AD Secure only dynamic updates. What does the cutover do?

6. Which statements about the DHCP switch and rollback are true?

Select all that apply.

Finished 3.6 Migration?
Mark it complete to track your progress (stored only in this browser).