3.6 Migrating to SpatiumDDI
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.
What you’ll learn
Section titled “What you’ll learn”- 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
The doctrine
Section titled “The doctrine”| 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.
Start with the lowest-risk step
Section titled “Start with the lowest-risk step”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.
Import: preview, then commit
Section titled “Import: preview, then commit”| 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-stubanddelegation-onlyzones; unquoted zone names; andincluded files. - Every created row is stamped with
import_sourceandimported_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).
Observe without writing to production
Section titled “Observe without writing to production”Observing means SpatiumDDI watches production without changing it:
- Register Windows DHCP read-only (a
DHCP Usersaccount) 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.
Cut over, one item at a time
Section titled “Cut over, one item at a time”- 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.
- 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.
- 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.
- 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. - 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
Section titled “Knowledge check”Go deeper
Section titled “Go deeper”- Migration: the importers and the Windows cutover in full
- Getting Started: project status: the IPAM-only evaluation pattern
- DNS features §12 and §14: Sync with Servers and the scheduled reconciliation jobs
- DHCP drivers: importing existing configs: the Kea, Windows and ISC parsers
- Windows Server setup: WinRM, service accounts, zone settings and Windows DHCP failover pairs