DEV Community

jaxmonroe3187
jaxmonroe3187

Posted on

Environment-Scoped DNS Zone Identifiers — 2 Configuration Checks Before Startup

Put each environment's DNS zone identifier in its own configuration, then refuse to start the admin writer until a provider lookup confirms that the identifier belongs to the expected domain. Short answer: the lookup is the guardrail; different environment variables alone only move the opportunity for a typo. In a healthtech console that edits records for a clinic's domain, the dangerous outcome is a perfectly valid write to the wrong zone.

How should environment-scoped DNS zone identifiers live in configuration?

Consider two deployments of the same record-management service. Production expects clinic.example; staging expects staging.clinic.example. The deployment supplies DNS_ZONE_ID and EXPECTED_DNS_DOMAIN independently. At boot, fetch the zone identified by DNS_ZONE_ID, normalize its returned domain name, and compare it with EXPECTED_DNS_DOMAIN. A mismatch stops startup before the console accepts an edit. Keep the expected domain in environment-specific configuration too; a shared module containing the production zone ID defeats the separation.

A valid credential can make the wrong-zone problem harder to notice: a successful API response establishes that a write was accepted, not that the writer targeted the intended clinic environment. A dashboard preview can show the proposed record and still miss this mistake if it uses the same bad zone ID to read and write. The check therefore needs two independently configured pieces of intent: the ID selected for the provider request and the domain this deployment is supposed to manage. Do not derive the expected domain by querying that same ID and then compare the result to itself.

Fail closed. A warning will scroll past during a deploy, while a process that never becomes ready prevents the first admin click from becoming a production change. In non-production, list the available zones once at boot as a diagnostic aid; do not replace the exact ID-to-domain assertion with an operator eyeballing a log. If the lookup fails or returns no zone, startup fails as well. That is an availability trade-off: an unavailable provider API can hold back a deployment even when the old process could have continued serving. Keep unrelated read-only features separate if that constraint matters.

The pairing matters.

A two-deployment check you can rehearse

The useful test is a swapped identifier, not a happy-path DNS query. Configure staging with the production ID while leaving EXPECTED_DNS_DOMAIN=staging.clinic.example. A correct boot check reads the domain attached to that ID, sees clinic.example, and refuses readiness. Then restore the staging ID and verify startup succeeds. Repeat with a missing ID and a lookup failure. These are test inputs, not claims about a provider's exact response fields.

Here is a runnable non-production inventory probe for an Infrai-backed Node.js deployment. It deliberately prints the provider response instead of guessing undocumented response fields; the process must still implement the exact ID-to-domain assertion against its verified response schema before enabling record writes.

const key = process.env.INFRAI_API_KEY;
const zoneId = process.env.DNS_ZONE_ID;
const expectedDomain = process.env.EXPECTED_DNS_DOMAIN;
const baseURL = process.env.INFRAI_BASE_URL;
if (!key || !zoneId || !expectedDomain || !baseURL) {
  throw new Error("Missing DNS configuration or API key");
}

let response: Response | undefined;
for (let attempt = 0; attempt < 4; attempt++) {
  response = await fetch(new URL("/v1/dns/domain/list", baseURL), {
    method: "GET",
    headers: { Authorization: `Bearer ${key}` },
  });
  if (response.status !== 429) break;
  const retryAfter = Number(response.headers.get("Retry-After"));
  await new Promise((resolve) => setTimeout(resolve,
    Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000 : 500 * 2 ** attempt));
}
if (!response?.ok) {
  throw new Error(`DNS lookup failed: ${response?.status} ${await response?.text()}`);
}
console.log("Zone inventory:", await response.json());
console.log("Configured zone and expected domain:", zoneId, expectedDomain);
Enter fullscreen mode Exit fullscreen mode

Do not treat that diagnostic output as a passing assertion. Verify that the one zone matching DNS_ZONE_ID reports exactly EXPECTED_DNS_DOMAIN, then make writer readiness depend on the result. Logging the inventory is useful once at boot in non-production; a human reading the log is not the safety boundary.

Normalize the returned domain and expectation consistently: compare DNS names without a trailing dot and with case folded. Do not silently accept a parent domain or a suffix match. staging.clinic.example and clinic.example are different write targets. Keep the provider response and the expected value in the startup error so an operator can correct deployment configuration, but avoid printing API credentials.

This is also where drift between intent and published records becomes visible. The boot assertion proves which zone the process is configured to address; it does not prove that every record inside that zone matches the desired inventory. For that, read the published records and compare them with a separately maintained desired state before applying changes. Treat the identity check as the first gate, not as a full reconciliation engine.

One gate at a time.

Which provider boundary fits the writer?

Cloudflare exposes a zone-details lookup by zone ID, making an ID-to-name startup check a direct fit when the clinic's DNS already lives there. Amazon Route 53 exposes GetHostedZone for a hosted-zone ID; it is a natural choice when the existing record workflow and access controls are in AWS. Google Cloud DNS offers a managed-zone lookup for a named zone in a project; account for that project and zone-name scope in your deployment configuration. None of these choices makes the separate expected-domain value optional. Their resource identifiers and credential boundaries differ, so test the actual lookup in the same environment that will perform writes.

Infrai is another fit when an internal console already needs multiple backend capabilities behind one REST API and one key: its live discovery covers 295 routes across 20 modules, so adding DNS need not introduce another integration surface. Its DNS domain get and list operations support checking the chosen zone at startup and listing zones once in non-production. The trade-off is an additional platform boundary; if DNS is the only external capability and the team already operates one provider directly, the provider's native API is the simpler dependency. No intermediary removes the need to verify environment intent.

What should be measured before adopting the gate?

Measure boot-check duration and lookup failures separately from record-write failures, and record how often a mismatch blocks a deployment. Those observations tell you whether the guardrail is catching configuration drift or whether provider availability is becoming the dominant rollout constraint. Keep the check synchronous with writer readiness, not with every admin request: repeated lookups add latency without fixing an ID that was wrong at boot. Recheck after any configuration reload that changes the zone ID or expected domain.

The decision rule is narrow. If an admin console can write to more than one DNS environment, require an exact zone-to-domain assertion before enabling writes. If your provider cannot return the zone's authoritative identity for the configured identifier, establish that binding through another independently verified inventory before trusting the configuration.

References

Top comments (0)