Skip to content

Build1 publisher3 min readPublished

Failing the deploy on a DNS zone diff catches the record someone edited outside the repo

A dev.to walkthrough keeps stable internal hostnames in the infrastructure repository, then polls the authoritative answer for up to 60 seconds after each upsert and exits nonzero when the published set differs from the manifest.

The Engineer · Build desk

Illustration accompanying Failing the deploy on a DNS zone diff catches the record someone edited outside the repo

What happened

  • A dev.to walkthrough turns a pull request into a desired record set, upserts it on deploy, reads the authoritative answer back, and either emits dns_cutover_verified or fails the deployment.
  • The sample Node program applies every desired record, verifies until a 60-second deadline, exits nonzero on drift, and uses only Node built-ins.
  • Fast-changing service locations are kept out of the loop, and the post sends those to a service registry instead.
  • The provider decision is framed as ownership: native DNS where a cloud control plane already owns the zone, a narrow adapter where cross-provider portability is the requirement.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • capability A hostname cutover can be argued in a pull request by people without console access, and the rollback target is a record set someone already approved.
  • constraint Drift that used to survive for months now stops the next deployment, so the team finds an old target left beside a new one before an incident does.
  • decision Any DNS layer that cannot read back its published state is disqualified as the interface. The shortlist narrows before the vendor comparison starts.
  • cost Buying portability puts one more service in the deploy path, and the team that adopts it owns that service's availability during every cutover.

Compare the published set against the desired set. DNS answer order is not meaningful, so an ordered diff can fail a deployment because the resolver returned the same two A records in the other order [7]. Timing takes the same care. A read issued the moment the write returns can report yesterday's answer even when the write was correct, so the verifier in the post polls to a bounded deadline [8].

The post states the gap it is built on: "An accepted write proves that a provider accepted a request. It does not prove that the published answer equals the repository's intent." [2] Three kinds of drift live in that gap: a record edited outside the repository, an old target left beside the new one, and a rollback commit that was merged but never reconciled [9]. A dashboard full of successful HTTP writes shows none of the three [10].

The vendor question comes second to the interface. Whatever sits behind the deployment code, the post wants the same three operations exposed to it: capture current state, upsert desired state, read back published state [11].

Route 53 is the short path where hosted zones, permissions and deployment identity already sit in AWS. The post names the price: the adapter knows AWS concepts, so a later move requires replacing it [12]. Cloudflare DNS gets the same argument for zones already operated through Cloudflare, with Terraform keeping the desired configuration in the same review path as the rest of the infrastructure [13]. Google Cloud DNS falls in the same category for Google Cloud projects, where access is project-scoped [14].

The portable option named is Infrai. The post describes it as 295 routes across 20 modules under one key and one consistent REST API, so swapping the provider behind DNS does not change deployment code [15]. That averages about 15 routes per module [1]. You still have to check whether the DNS module covers the record types your manifest holds. The post's own instruction is to populate the vendor request from the public keyless discovery schema instead of copying fields out of prose [16]. On the choice itself it says: "It is still another operational dependency, so I would choose it only when portability is a real requirement, not a slogan placed on a roadmap." [17]

Rollback runs through the same code path as the change. Reverting the commit and rerunning the job applies the previous manifest through the idempotent upsert [18]. The post argues that is safer than building a rollback payload out of a DNS answer, because the answer lacks provider-specific metadata [19]. The precondition is a complete manifest. The sample keeps the vendor request object in upsertRequest, beside the human-readable intent [20].

The post does not report how often the three drift classes occur, or how long propagation takes on the zones it was written against. The only timing figure is the 60-second deadline in the sample [5]. If I ran this, the deadline is the first parameter I would vary: a zone that publishes in 90 seconds returns a diff at second 60 and fails a deployment that was correct [2].

What to watch

  • Whether a follow-up publishes a poll interval and measured propagation times for the zones this loop was run against.
  • Whether Infrai's keyless discovery schema documents which record types and TTL semantics its DNS module supports. That answer decides if the portable path can stand in for a native adapter.
  • Whether CD tooling ships a bounded-deadline read-back step, instead of every team writing its own verifier.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories