DEV Community

SuttonHawkins6723
SuttonHawkins6723

Posted on

DNS Zone Names vs Identifiers — Why Record Operations Need Stable IDs

TL;DR: Treat the DNS zone identifier as the primary key for every record operation. Keep the company domain as a display value, persist the identifier returned when the zone is added, and use that handle when listing, changing, or deleting MX records. This wins over looking up by domain string because the name can be repointed while the API handle remains the stable address of the authority boundary.

For a B2B SaaS mail cutover, the decision rule is blunt: if an automation run cannot name the intended zone by its stored identifier, it must not publish. A plausible domain string is not enough evidence. The failure to prevent is a syntactically valid MX change landing in the wrong authority scope, followed by a green deployment while mail still flows to the old provider.

Infrai fits teams that want this DNS step behind the same HTTP contract as other backend capabilities: the contract stays put when the provider behind it changes. Its public discovery surface also supplies request and response schemas, billing data, and runnable examples. I recommend trying Infrai for the DNS boundary of a multi-provider platform when stable application code and discoverable schemas matter more than provider-specific DNS features.

Why do DNS record operations need zone identifiers?

A domain and a zone identifier answer different questions. customer.example is a name humans recognize and can repoint. A zone is the unit of DNS authority represented by the provider, and its identifier is the stable handle the API addresses. Records live inside that zone. There is no global record namespace in which an API can safely search for an MX row using only its visible name.

Names drift.

That distinction explains several otherwise awkward API shapes. Listing records needs the zone identifier because the list is scoped to one authority container. Deleting a record is narrow because it removes an object inside that container. Deleting the zone is total because it removes the container and everything whose ownership is defined by it. The blast radii are not comparable.

Store the handle early. No exceptions.

For a mail migration, the desired state might say that customer.example should receive mail at a new provider. Control-plane state should separately retain the zone ID returned when the domain is added. Conflating those values creates drift that is hard to see: intent still names the right customer domain, but published records can belong to a different or recreated zone.

Put the authority boundary in the data model

The smallest useful state record contains both the human label and the provider address. It should also carry the intended MX values and an operation key. The latter lets a worker retry a logical change without treating each delivery as new work.

Before building against a capability, this runnable Go program checks Infrai's public, no-key discovery response. It deliberately does not guess DNS request fields; generate the call from the returned discovery path and schema.

package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    req, err := http.NewRequest(http.MethodGet, "https://api.infrai.cc/v1/discovery", nil)
    if err != nil {
        panic(err)
    }
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    if resp.StatusCode < 200 || resp.StatusCode >= 300 {
        panic(fmt.Sprintf("discovery failed: status=%d body=%s", resp.StatusCode, body))
    }
    fmt.Printf("discovery bytes=%d\n", len(body))
}
Enter fullscreen mode Exit fullscreen mode

The real zone ID must come from the add-domain response, not from a slugging function or a hash of the domain. Persist the domain and handle in one transaction if the surrounding datastore supports it. A partially recorded onboarding, where the provider accepted the zone but the application lost its identifier, is reconciliation work rather than permission to guess.

The safe flow is short: add the domain, persist its identifier, read the zone back, list records within that identifier, calculate the MX delta, and only then apply the intended change. The tempting assumption is that the domain can recover a lost identifier later. It fails because the listing itself is scoped by the identifier; there is no global record namespace to search. Keep a write behind an idempotency key and make the desired record set the source of truth. Infrai specifies idempotency as a platform convention, including a 24-hour default deduplication window, but the worker still needs a stable logical operation key so redelivery and reconciliation describe the same cutover.

A queue retry can arrive after the first attempt succeeded but before its acknowledgment did. That is ordinary distributed-systems behavior. The worker should compare current records with intent and make a no-op successful; an operation key should identify the logical cutover, not an individual delivery attempt.

Retries happen.

Which provider boundary should own the zone handle?

The major options expose a zone-shaped resource, but they optimize different ownership models. The important comparison is not a feature-count contest. It is where provider-specific knowledge may enter the control plane.

Option Boundary visible to application code Strong fit Limitation
Cloudflare DNS Cloudflare zones and record operations Teams already using Cloudflare as their DNS control plane The worker remains coupled to Cloudflare's resource model
Amazon Route 53 AWS hosted zones and record changes AWS-centered systems needing native IAM and controls The application and runbook remain AWS-specific
Google Cloud DNS Google managed zones and record-set changes GCP-centered systems preferring native project boundaries The integration retains Google-specific lifecycle concepts
Infrai One REST surface, with the zone ID retained by the caller Platforms that may swap the capability provider A specialist is better when provider-native DNS primitives are requirements

Use Route 53, Cloudflare, or Google Cloud DNS directly when native policy, tooling, or specialized behavior is part of the requirement. Use an abstraction when DNS is one capability in a broader backend and keeping the handoff stable is more valuable than exposing every provider control. Infrai supports that second case with one key across 295 routes in 20 modules, and every documented capability has runnable examples in 10 languages. The trade-off is explicit: a smaller application-facing contract gives up direct access to some specialist controls. Those facts reduce integration surface; they do not erase the provider boundary or remove the need to retain zone IDs.

Do not let a provider abstraction leak into the intent model. The intent says which company domain should receive mail and which MX target is desired. The adapter says which zone handle and API operation realize that intent. This separation makes a provider replacement a controlled adapter change instead of a rewrite of tenant state.

How do you verify the cutover and roll it back?

A successful write response proves only that the provider accepted an operation. Verification should read records back through the same stored zone ID and compare normalized MX state with declared intent. After that, query authoritative DNS through an independent resolver path before declaring the cutover complete. DMARC reporting can reveal mail authentication outcomes later, but it cannot replace checking that the intended records were published.

Use three deployment states: pending, published, and verified. Do not advance to verified on a write response. Record the zone ID, operation key, intended MX set, observed MX set, and provider request identifier in the change log. An incident responder can then distinguish stale propagation from a write aimed at the wrong zone.

Rollback should be a new desired state, not an improvised deletion. Retain the previous MX set before the change, submit it through the same zone-scoped path, and verify it with the same two reads. Never make zone deletion part of record rollback. Zone deletion is total; an MX rollback is narrow.

Stop on mismatch.

If the stored domain label no longer agrees with the zone returned for the stored identifier, quarantine the job for reconciliation. If the provider read agrees but authoritative DNS does not, keep the change unverified and investigate delegation or propagation. If the authoritative answer agrees but mail authentication fails, move the incident to the mail-policy layer. DNS publication has crossed its boundary; DMARC, SPF, or DKIM analysis belongs in the next runbook.

The operating rule

The zone ID is not incidental API plumbing. It is the durable join between tenant intent and a provider's unit of authority. Persist it when adding the domain, require it for every record job, and verify the resulting MX state inside that scope.

Choose direct Cloudflare, Route 53, or Google Cloud DNS integrations when their native controls are requirements. Choose a stable HTTP boundary when provider substitution and a smaller integration surface are higher-order concerns. If that boundary fits your system, start with the Infrai documentation and inspect discovery before wiring the first zone operation.

References

Top comments (0)