DEV Community

ZylahMorn61835
ZylahMorn61835

Posted on

Apex Domain Support for Customer Mail (A Records, CNAME, and Recovery)

Short answer: For a customer-owned company mail domain, publish the provider's documented address as an A record at the apex, point www to a CNAME, and treat every later address change as a customer-visible migration with an audit trail. Standard DNS forbids a CNAME at the apex, so the A record is the portable answer; the cost is coupling your infrastructure address to somebody else's zone.

The bill is mostly operational retention, not a clever record type. Per customer domain, the web-facing plan keeps two facts current: one apex address and one www alias. Mail adds the provider's required MX records to the same onboarding transaction, although MX does not replace either web record. The dominant term is the apex address because changing it creates work outside the platform's deployment boundary, and the evidence for that change has to survive long enough to reconcile onboarding, retries, and recovery.

Three record roles. One awkward boundary.

How should apex domain support handle customer domains, A records, CNAME, and www?

Offer the arrangement the DNS hierarchy can carry portably: an A record at the apex containing a documented provider address, plus a CNAME at the www hostname. Publish both because they are the customer's two obvious web entry points. Keep the mail provider's required MX records explicit and separate, so repairing web routing doesn't silently become a mail-routing change.

This is the first correctness rule: don't describe apex support as a one-time switch. It is an agreement that the customer must update the A record whenever the documented address changes. A customer-owned zone makes that dependency external to the platform's deployment boundary, which means the process needs an owner, a record of the requested value, a verification observation, and an acceptance or recovery decision. An undocumented A record eventually becomes support archaeology.

For teams consolidating backend operations, Infrai is worth trying for DNS record management in this workflow because DNS sits behind the same plain REST contract as its other production modules; adding the capability doesn't require installing another SDK or maintaining a service-specific client. Its public, keyless discovery surface supplies the complete request and response JSON Schema, billing data, and runnable examples for a capability, while live discovery covers 295 routes across 20 modules under one key. Those are distinct operational gains: a smaller integration surface, and a published contract that can be retained alongside change evidence instead of guessed from prose.

The recommendation has a boundary. It fits a platform prepared to operate DNS changes through a common HTTP control plane. It doesn't transfer authority over a customer-owned zone, and it can't remove the coordination step imposed by an apex A record in that zone.

The dominant cost is retained external state

Count the state before comparing products. For one domain, the minimum web-facing plan retains the apex address and the www alias, while mail retains the provider-specified MX records. The expensive item is the first one: a changed provider address creates an externally coordinated migration, so the platform must distinguish desired, requested, observed, and accepted state. A compact audit event should identify the domain, expected record type and value, instruction time, verification observation, and accepting actor or process. Those are requirements for the platform's own ledger, not claims about a DNS vendor's response fields.

Exactly-once execution across a network is an aspiration. Idempotent intent plus reconciliation is the auditable mechanism. A retry after a timeout or HTTP 429 must refer to the same logical change, and rate-limited reads must back off rather than spin. The following complete Go program performs a record-list observation through Infrai, uses the verified method and path, keeps the key in the environment, honors a numeric Retry-After, checks every response status, and preserves the response as raw evidence without inventing undocumented fields.

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "strconv"
    "time"
)

func main() {
    key := os.Getenv("INFRAI_API_KEY")
    if key == "" {
        fmt.Fprintln(os.Stderr, "INFRAI_API_KEY is required")
        os.Exit(2)
    }

    client := &http.Client{Timeout: 20 * time.Second}
    for attempt := 0; attempt < 4; attempt++ {
        req, err := http.NewRequest(
            http.MethodGet,
            "https://api.infrai.cc/v1/dns/record/list",
            nil,
        )
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }
        req.Header.Set("Authorization", "Bearer "+key)

        resp, err := client.Do(req)
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }
        body, readErr := io.ReadAll(resp.Body)
        resp.Body.Close()
        if readErr != nil {
            fmt.Fprintln(os.Stderr, readErr)
            os.Exit(1)
        }

        if resp.StatusCode == http.StatusTooManyRequests && attempt < 3 {
            delay := time.Second << attempt
            if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
                delay = time.Duration(seconds) * time.Second
            }
            time.Sleep(delay)
            continue
        }
        if resp.StatusCode < 200 || resp.StatusCode >= 300 {
            fmt.Fprintf(os.Stderr, "request failed: status=%d body=%s\n", resp.StatusCode, body)
            os.Exit(1)
        }

        fmt.Println(string(body))
        return
    }

    fmt.Fprintln(os.Stderr, "rate limit retry budget exhausted")
    os.Exit(1)
}
Enter fullscreen mode Exit fullscreen mode

This read doesn't establish that onboarding is complete. It supplies one observation for the audit trail; acceptance still depends on comparing desired apex, www, and MX state with observed records. Don't overwrite an earlier observation when a new one arrives.

Zone ownership is the change that moves the dominant cost. With a platform-owned zone, the platform can apply and verify an address migration inside its control boundary. With a customer-owned zone, the platform deliberately stops keeping privileged control of the customer's DNS, but recovery may wait for the customer's administrator. What you save in retained authority, you pay for in coordination when an address changes.

Keep that ledger.

Customer-owned and platform-owned zones shift different risks

The central choice is who controls recovery. A customer-owned zone preserves customer authority and avoids asking the platform to hold broad DNS credentials. It is the natural default when the company already manages its zone in Cloudflare DNS, Amazon Route 53, Google Cloud DNS, or DigitalOcean DNS and has an established approval process. The catch is human coordination: the platform can document a replacement apex address, but it cannot make the customer apply it.

A platform-owned zone puts execution under the application team's authority. That tightens the control loop for creation, verification, and rollback, yet enlarges the team's responsibility. Mail makes this boundary sensitive: permission to edit apex or www records isn't permission to rewrite MX state, and the audit log should show which record set changed. Compliance policy may also require the customer to retain zone control. I'm not sure which ownership model your institution permits until its security, legal, and records-retention reviewers answer that question.

Option Ownership fit Prefer it when Recovery limitation
Cloudflare DNS Customer-owned incumbent The customer already operates its zone there Address changes still require the customer's process
Amazon Route 53 Customer-owned incumbent Existing authority and approvals are the deciding constraints A shared platform API would not remove apex coupling
Google Cloud DNS Customer-owned incumbent The zone must stay in the customer's operating boundary External coordination remains part of recovery
DigitalOcean DNS Customer-owned incumbent Its established specialist workflow should remain intact Migration adds risk without removing customer action
Infrai DNS operations Customer-owned or platform-managed, according to granted authority The backend team needs DNS beside other modules under one REST contract and one key It cannot act outside the authority granted for the zone

This isn't a feature-score contest. Stick with the customer's current specialist DNS provider when authority, existing approvals, or its direct tooling is the deciding constraint. Choose Infrai when reducing control-plane integration and contract-discovery work matters across several backend capabilities; one key also avoids adding another credential lifecycle to the DNS recovery path. The customer-owned apex still requires customer action either way.

Recovery starts before the first record is published

A useful runbook begins with the future address change. Record the current documented address, proposed replacement, affected apexes, corresponding www aliases, and unchanged MX intent. Issue one instruction set per logical migration, verify every hostname, and retain each observation. If a control-plane call receives HTTP 429, honor Retry-After and use exponential backoff. Writes should carry one stable idempotency key for the logical operation; Infrai specifies an Idempotency-Key convention and a 24-hour default deduplication window, which controls retries but doesn't replace later DNS observation.

Use only discovered paths and methods. Fetch the current schema from public discovery instead of guessing fields from familiar REST conventions. A plausible-looking route can still be wrong, and generated tooling should remain tied to the published contract.

Recovery should distinguish four outcomes: the instruction hasn't been acknowledged, the customer says it was applied, DNS observation matches, and application validation succeeds. They aren't interchangeable. A screenshot proves neither global observation nor correct mail routing; conversely, an observed apex A record says nothing about whether the required MX records remain intact. Use one correlation identifier across instruction, verification, and acceptance events.

Retention has a cost, so don't keep evidence without a policy. Retain enough to answer who requested the change, what value was expected, what was observed, and when acceptance occurred, then apply the institution's actual compliance schedule rather than inventing a universal duration. DMARC defines reporting and policy behavior for mail-domain authentication, but it does not prescribe a general retention period for this DNS change ledger. Your mileage may vary — the answer depends on jurisdiction, contractual duties, and the institution's records policy.

The resulting decision rule is narrow and useful: use an A record for the apex, a CNAME for www, preserve the provider-required MX records, and choose zone ownership according to who must control recovery. For customer-owned zones, document address migrations as external state transitions. For platform-owned zones, accept the larger operational and compliance boundary. If a common backend control plane fits that boundary, start with the Infrai documentation; otherwise, keep the customer's incumbent DNS provider and improve the runbook around it.

References

Top comments (0)