Skip to content

External providers

The optional dns_external submodule connects local zones and records to remote DNS provider accounts (ClouDNS, Route 53, Cloudflare, …) so you can import zones from the provider into Drupal or push local changes back out.

dns_external is the framework: the plugin manager, the binding entity, the importer, and the pusher. Each concrete provider ships as its own module that registers a Provider plugin against this framework. ClouDNS's integration is dns_cloudns; others (Route 53, Cloudflare) are similarly named. Enable the framework first, then the provider modules you actually use.

Install

The framework has a hard dependency on the Key module. The dns module itself doesn't pull Key in — sites that don't need dns_external shouldn't carry the cost — so you have to require it explicitly before enabling the submodule:

composer require drupal/key
drush en dns_external
drush en dns_cloudns        # or whichever provider module you need

Provider plugins store secret credential material (passwords, API tokens) as references to Key entities, never as raw secrets in module config. Non-secret identifiers (account ids, usernames, endpoint URLs) live in plain config; wrapping them in Keys would add friction without protecting anything.

Concepts

Term What it is
Provider plugin The integration class for one DNS service (ClouDNS, Route 53).
Provider configuration A Drupal config entity holding one provider account (a label, the plugin id, and plugin-specific settings — secret credentials referenced by Key id, identifiers in plain config). One per account; you can run two ClouDNS accounts and a Route 53 account on the same site.
External binding A content entity that ties one local zone to one provider account. Carries the provider's id for that zone (provider_remote_id) plus any free-form metadata the plugin chose to round-trip.

A zone is bound to at most one provider account at a time; multi-provider mirroring isn't a goal of this version.

Add a provider account

  1. Go to Configuration → Services → DNS provider configurations (/admin/config/services/dns_external/providers).
  2. Click Add provider configuration, pick the provider plugin (e.g. ClouDNS), then Continue.
  3. Fill in the plugin's settings form. Plain identifier fields (account id, username, endpoint URL) accept text directly; secret fields point at Key entities — create the Key first (Configuration → System → Keys) if you haven't already. The label is admin-facing only; pick something that distinguishes the account if you run more than one (e.g. ClouDNS — production, ClouDNS — staging).
  4. Save. The configuration appears on the collection page.

Import zones from a provider

  1. From the provider configuration collection, click Import zones.
  2. Pick the provider account whose zones you want to discover.
  3. The next page lists every zone the provider account exposes. Tick the ones you want to bring into Drupal and click Import selected.

What happens per zone:

  • A local dns_zone is created (Punycode-canonicalized).
  • All records the provider returns are materialized as dns_record entities. Each carries the provider's id for that record (provider_remote_id) so the pusher can later update them in place rather than re-creating duplicates.
  • A binding entity is created tying the zone to the provider account.

What import refuses

The importer refuses to import into an existing local zone — if a dns_zone with the same name already exists in Drupal, the row in the discovery list is disabled with a "delete first to re-import" hint. Re-import / merge semantics ship with bidirectional sync; until then, delete the local zone first if you want to bring in the provider's copy fresh.

What import skips

Per record, the importer skips and logs rather than aborting the zone:

  • Unsupported record types: anything outside the eleven core types plus the seven dns_extras types (DNAME, SSHFP, TLSA, SMIMEA, OPENPGPKEY, DS, DNSKEY). Watch the dns_external log channel; the count appears in the on-screen summary.
  • Records that fail validation: malformed targets, out-of-range TTLs, IP addresses in the wrong family, etc. The same log channel carries the per-record reason.

Mass-import success is reported with a count; partial success (records skipped) renders as a warning so you know to inspect the log.

Push a zone to its provider

The push button lives on each zone's binding page: /dns/{zone}/externalPush to provider.

A confirmation page summarizes the scope (zone name, provider account) before submission, since the operation writes to a remote account that may serve more than one zone.

What push does, per record:

Local state Action
Record has no provider_remote_id Calls the plugin's pushRecord. Stamps the returned id back on the local record.
Record has a provider_remote_id Calls pushRecordUpdate. The remote id is preserved.

If the binding has no provider_remote_id yet (you're pushing a locally-created zone for the first time), push also calls pushZone once and stamps the returned id on the binding.

What push does NOT do

  • It doesn't sync deletes. A record you delete locally is not removed from the remote — until bidirectional sync ships, you have to delete those by hand on the provider side. The reason is scope: a sync that touches deletes needs a diff against the remote, which is a different operation than the strict local→remote write this push performs.
  • It doesn't update the zone metadata after first push. The one-time pushZone call sets things like the zone type (master / slave / geo for ClouDNS); changes to those settings via the binding edit form aren't synced. If you need to change zone-level metadata on the remote, do it in the provider's own console for now.

Failure modes

  • Zone-level failure (pushZone itself fails): nothing is written remotely or locally. Status is reported as failed; check the log for the API response.
  • Per-record failure: the loop continues. Records that succeeded keep their stamped provider_remote_id; the failed ones don't, so a re-push tries them again as creates. The result message shows a N created, M updated, K failed summary.

A re-run of push is the standard recovery for transient API issues.

Permissions

Permission What it grants
administer dns providers Add / edit / delete provider configurations and bindings; run import; run push. Restricted access.
view records on a zone (per-zone) View the binding row on /dns/{zone}/external so zone owners and granted collaborators can see whether their zone is bound and to which provider account.

Mutating provider configurations and bindings stays admin-only in this version because credentials and remote-API responsibility are admin concerns. Zone owners and granted collaborators can see that their zone is bound, but not change the binding.