Skip to content

Promote a pilot to production

The pilot worked: four zones, health checks, the failover demo that convinced everyone. Promotion is not “make the pilot bigger”, it is standing up a production cluster born with its own secrets and moving the DNS data across, deliberately leaving behind the pilot’s users, tokens, and, above all, its cluster encryption key. This tutorial is that path.

Terminal window
curl -sk https://<pilot-node>:8443/api/v1/zones/export \
-H "Authorization: Bearer $DTM_TOKEN" -H "X-DTM-CSRF: 1" -o pilot-zones.json

The JSON bundle carries zones, records, LB policies, health-check templates, and region tags; system SOA/NS records re-synthesize on import. It contains no secrets: probe credentials (OAuth2 client secrets, mTLS key material, auth headers) are redacted before serialization. Treat the file as sensitive anyway, because it maps your internal namespace, but it is topology-sensitive, not credential-bearing.

There is a second way to move data between clusters: an offline restore of a full snapshot. A snapshot is bound to its origin cluster’s encryption key, so restoring one elsewhere needs that key. Changed in v1.0.6: given the pilot’s key in a file (restore --local --source-key-file), the offline restore re-keys the snapshot’s secrets to production’s key, so they carry across readable; without it, the restore refuses the snapshot (details). It restores the entire local data store, which is precisely the problem: it drags along pilot users, service accounts, audit history, and every secret the pilot held, now readable in production.

For promotion, the bundle wins: DNS data only, clean identity slate, and no pilot secret arrives in production. Keep the cross-cluster restore for disaster scenarios, as a deliberate act.

3. Deploy production with its own birth certificate

Section titled “3. Deploy production with its own birth certificate”

Deploy the dual-region production cluster (the Marketplace 4-node HA, two regions option, or the Terraform path; the dual-region tutorial walks the cross-region prerequisites gate, replication proof, and failover drill end to end, on the smaller one-node-per-region layout). The fresh deployment generates its own first-boot secrets, the initial administrator password and the cluster encryption key, into its own Key Vault.

Retrieve the initial admin password with the deployment’s recoverAdminAccessCommand output (retrieveAdminPasswordCommand in the Bicep dialect), change it, and run the production readiness pass now, before the data arrives: named accounts and break-glass admin, Entra SSO with the private-window interlock, scoped NSGs, scheduled backups. Hardening an empty cluster is strictly easier than hardening a serving one.

5. Import the bundle, then re-enter probe credentials

Section titled “5. Import the bundle, then re-enter probe credentials”

Dry-run first, commit second (limits: 20 MB, 50 zones, 50,000 records per zone):

Terminal window
curl -sk -X POST "https://<prod-node>:8443/api/v1/zones/import?dry_run=true" \
-H "Authorization: Bearer $DTM_TOKEN" -H "X-DTM-CSRF: 1" \
-H "Content-Type: application/json" --data-binary @pilot-zones.json
# review, then re-send without dry_run

Verify zones and records arrived (API counts plus a few digs), then do the step the redaction makes mandatory: re-enter every authenticated probe’s credentials (OAuth2 secrets, mTLS material, auth headers) on the production cluster. They did not survive the round trip by design, and without them authenticated probes fail quietly in production.

The bundle moves DNS data; a six-week pilot accumulated more than that. Recreate deliberately, each with its owning page:

Assign the Azure Policy pack in its default DoNotEnforce mode, so the production estate starts life with the audit trail on and the rollout tracker ready for step 8’s waves.

Move client VNets from the pilot node’s IP to the production cluster’s stable IPs, wave by wave, verifying each with dig and the dashboard (local-node-first ordering per the dual-region tutorial).

Let the pilot and production run in parallel until the pilot’s own metrics say it is done: watch the pilot’s query rate (rate(dtm_dns_queries_total[5m]), or the dashboard’s QPS panel) fall to and stay at zero (the raw counter is monotonic and never falls). A pilot still answering queries is a client you forgot.

  • Revoke pilot service accounts (POST /api/v1/service-accounts/{id}/revoke); disable or delete pilot local users. Bearer login tokens need nothing: they are 24-hour self-expiring JWTs.
  • Delete the pilot’s Azure resources (VM, disk, NIC, Key Vault per your retention policy).
  • Mark old pilot snapshots as historical. They remain bound to the pilot cluster, so restoring one into production would require the pilot’s encryption key, passed deliberately with --source-key-file, which is exactly the friction you want in front of that mistake. Once the pilot’s Key Vault is gone and no copy of its key survives, its snapshots cannot be restored anywhere.

Production is now serving on its own secrets, its own hardening, and its own evidence trail, and nothing of the pilot survives but the DNS data that earned the promotion.

Need a hand? Email [email protected].

Last validated: 2026-07-26