The provider layer
RedundantDNS keeps one canonical copy of each zone and writes it to two or more DNS providers. Everything provider-specific lives behind one small Go interface, so adding a provider never touches the product code. This page explains that layer for engineers and for curious customers: the contract every adapter implements, the two access levels, what each provider can serve, and what managed mode means per provider.
The adapter contract
Every provider is an adapter behind providers.Provider
(pkg/providers/provider.go in the platform source). Adapters
are pure translators between the canonical model (pkg/dnscore) and one
provider's API: no UI, no storage, no product logic, and they never read
ambient credentials (~/.aws, ~/.oci, ~/.config/gcloud, ~/.azure or
CLOUDFLARE_*). Each one is tested with a fake SDK client, never against a
cloud.
| Method | What it does |
|---|---|
Capabilities() | What the provider can serve (the matrix below). A zone's effective capability is the intersection over its providers, checked on the server before any write. |
ValidateCredentials | Checks a grant for an access level: list zones (create and manage) or read the one zone given (manage an existing zone). |
CreateZone / DeleteZone / FindZone | Zone lifecycle; FindZone finds a zone by id or by name for adoption. |
ListRecordSets | What the provider serves, as canonical record sets (SOA excluded, apex NS included). |
ApplyChanges | Applies a diff (create, update, delete per name and type). Idempotent: a retry after a partial failure converges. |
QueryMetrics | Query counts of a zone over a period (managed-mode billing); nil when the provider does not expose them. |
Two optional interfaces cover provider quirks: ZoneStatusReader (a
provider-side zone status the customer must see, Cloudflare's "pending" or
"moved") and ZonePreparer (a setting to change before the platform
manages an adopted zone: Cloudflare's Multi-provider DNS).
The data plane is the only caller: it diffs the canonical zone plus the apex NS plan (the union of every attached provider's nameservers) against what each provider serves, applies the diff on reconcile, and records drift on verify. A change made directly at a provider is never overwritten silently.
Access levels
Each connection grants one of two levels. Each provider's guide lists the exact permissions.
| Level | What RedundantDNS can do |
|---|---|
Create and manage zones (zone_admin) | Create the zone at the provider, write its records and apex NS, and delete it when you detach (only after you type the zone name). |
Manage an existing zone (zone_editor) | Read and edit the records of a zone you created and whose id you give per attachment. It never creates or deletes zones. |
Capability matrix
Numbers come from each adapter's Capabilities value and its comments in
pkg/providers/<provider>/; where a provider does not document a bound,
the adapter uses a conservative one, marked "from the code".
| Route 53 | OCI DNS | Google Cloud DNS | Azure DNS | Cloudflare | |
|---|---|---|---|---|---|
| Record types | A, AAAA, CNAME, MX, TXT, SRV, CAA, NS, PTR | same | same | same | same |
| TTL range (seconds) | 0 to 2,147,483,647 | 1 to 604,800 (from the code) | 1 to 2,147,483,647 (from the code: not documented) | 1 to 2,147,483,647 | 60 to 86,400 (30 on Enterprise; not used) |
| Apex NS editable | yes | yes | yes | yes, Azure's own four are always kept | yes, with the Multi-provider DNS setting (turned on by the adapter) |
| Wildcards | yes | yes | yes | yes (not for NS and SOA) | yes |
| CNAME at the apex | no | no | no | no | yes (CNAME flattening) |
| Max values per record set | 100 (from the code: Route 53's real cap is request-size based) | 100 (from the code) | 10,000 | 20 | no documented limit |
| TXT length (characters per value) | 4,000 (from the code) | 4,000 (from the code) | 4,000 (from the code: 255 per string, 100 KB per change) | 4,096 per record set | 2,048 per record (8,192 per name and type) |
| Batching | ChangeResourceRecordSets: up to 1,000 changes and 1,000 values per request (an upsert counts its values twice) | one idempotent PUT or DELETE per record set | one change per batch: up to 1,000 additions, 1,000 deletions and 100 KB of data | one call per record set, deletes first | batch endpoint: delete and repost a set's records in one request, up to 200 operations each |
| Zone status reading | no | no | no | no | yes: initializing, pending, active, moved |
| Query metrics (managed billing) | yes: CloudWatch DNSQueries, daily sums | not yet | not yet | not yet | not yet (DNS analytics API planned) |
The intersection rule means a zone attached to Cloudflare accepts only TTLs from 60 seconds to one day, a zone attached to Azure at most 20 values per record set, and so on: the dashboard, the API and MCP refuse a record set that one of the zone's providers cannot serve.
Known quirks
- Cloudflare: Multi-provider DNS. Cloudflare only honours NS records at the zone apex when the zone's Multi-provider DNS setting is on. The adapter turns it on when it creates a zone, when a zone is adopted and before it writes the apex NS set; the API token therefore needs to edit the zone's DNS settings. Records are always written with the proxy off. See Cloudflare.
- Cloudflare Registrar. A domain registered at Cloudflare Registrar can only use Cloudflare's nameservers, so its delegation can never list other providers. The delegation check detects it (RDAP) and the dashboard explains the options: transfer the registration, use subdomain redundancy, or keep Cloudflare as one provider with a single-provider apex. See Cloudflare Registrar.
- Azure keeps its own NS. Azure refuses to remove its four nameservers from the apex NS set; the NS plan always contains them, so nothing is lost. See Azure DNS.
- Google Cloud: project-wide roles. Cloud DNS has no per-zone permissions: "Manage an existing zone" can edit every zone of the project. Keep a zone that must be isolated in a dedicated project. See Google Cloud DNS.
- Route 53 deletes need the exact set. Deleting a record set requires its current TTL and values; the adapter reads them first, so retries stay idempotent. See Route 53.
- OCI writes per record set. The adapter uses one PUT per record set rather than PATCH operations, which depend on the set's current contents. See OCI DNS.
Subdomain redundancy
A zone created as a subdomain of another zone of the same organization
(api.example.com under example.com) can have its NS delegation written
into the parent zone by the platform, kept equal to the child's nameserver
plan and removed when the child is deleted. The parent may be served by any
provider, including Cloudflare with "Manage an existing zone" access: the
delegation is an ordinary NS record set in the canonical parent zone,
marked as managed so nobody edits it by hand.
Managed mode per provider
On paid plans a connection can use an account that RedundantDNS operates ("managed") instead of yours. The connection carries no credentials: the data plane resolves the platform account from its own configuration. The access level is always "Create and manage zones", there is at most one managed connection per provider per organization, and the organization accepts the Managed Provider Terms once. The provider's cost is passed through at list price plus our margin, line by line on the Billing page.
| Provider | Managed account | Pass-through basis |
|---|---|---|
| Route 53 | an AWS account of ours | hosted zones per month plus queries (CloudWatch DNSQueries) |
| OCI DNS | an OCI tenancy of ours | queries (no zone fee); query metrics not read yet |
| Google Cloud DNS | a Google Cloud project of ours | managed zones per month plus queries; query metrics not read yet |
| Azure DNS | an Azure subscription of ours | zones per month plus queries; query metrics not read yet |
| Cloudflare | a Cloudflare account of ours | no DNS charge on Cloudflare's plans today |
Which providers are offered in managed mode depends on the accounts the platform has configured; the connection form only shows the managed option where one exists.