IGNORE_EXTERNAL_DNS
IGNORE_EXTERNAL_DNS makes DNSControl automatically detect and ignore DNS records managed by Kubernetes external-dns.
Background
External-dns is a popular Kubernetes controller that synchronizes exposed Kubernetes Services and Ingresses with DNS providers. It creates DNS records automatically based on annotations on your Kubernetes resources.
External-dns uses TXT records to track ownership of the DNS records it manages. These TXT records contain metadata in this format:
"heritage=external-dns,external-dns/owner=<owner-id>,external-dns/resource=<resource>"When you have both DNSControl and external-dns managing the same DNS zone, conflicts can occur. DNSControl will try to delete records created by external-dns, and external-dns will recreate them, leading to an endless update cycle.
How it works
When IGNORE_EXTERNAL_DNS is enabled, DNSControl will:
Scan existing TXT records for the external-dns heritage marker (
heritage=external-dns)Parse the TXT record name to determine which DNS record it manages
Automatically ignore both the TXT ownership record and the corresponding DNS record
External-dns creates TXT records with prefixes based on record type:
a-<name>for A recordsaaaa-<name>for AAAA recordscname-<name>for CNAME recordsns-<name>for NS recordsmx-<name>for MX recordssrv-<name>for SRV recordstxt-<name>for TXT records (when external-dns manages TXT records)
For example, if external-dns creates an A record at myapp.example.com, it will also create a TXT record at a-myapp.example.com containing the heritage information.
Usage
// Default: detect standard external-dns prefixes (a-, cname-, etc.)
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
IGNORE_EXTERNAL_DNS(),
// Your static DNS records managed by DNSControl
A("www", "1.2.3.4"),
A("mail", "1.2.3.5"),
MX("@", 10, "mail"),
// Records created by external-dns (from Kubernetes Ingresses/Services)
// will be automatically detected and ignored
);Custom Prefix Support
If your external-dns is configured with a custom --txt-prefix (as documented in the external-dns TXT registry docs), pass that prefix to IGNORE_EXTERNAL_DNS():
// If external-dns is configured with --txt-prefix="extdns-"
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
IGNORE_EXTERNAL_DNS("extdns-"),
A("www", "1.2.3.4"),
);This will match TXT records like extdns-www, extdns-api, etc.
Without a prefix argument, it detects:
The default
%{record_type}-format (prefixes likea-,cname-, etc.)Legacy format (TXT record with same name as managed record)
Example scenario
Suppose you have:
A Kubernetes cluster running external-dns with
--txt-owner-id=my-clusterAn Ingress resource that creates an A record for
myapp.example.compointing to10.0.0.1
External-dns will create:
An A record:
myapp.example.com→10.0.0.1A TXT record:
a-myapp.example.com→"heritage=external-dns,external-dns/owner=my-cluster,external-dns/resource=ingress/default/myapp"
With IGNORE_EXTERNAL_DNS enabled, DNSControl will:
Detect the TXT record at
a-myapp.example.comas an external-dns ownership recordIgnore both the TXT record and the A record at
myapp.example.comOnly manage the records you explicitly define in your
dnsconfig.js
Comparison with other options
IGNORE_EXTERNAL_DNS
Automatically ignore all external-dns managed records
IGNORE("*.k8s", "A,AAAA,CNAME,TXT")
Ignore records under a specific subdomain pattern
NO_PURGE
Don't delete any records (less precise, records may accumulate)
Caveats
One per domain
Only one IGNORE_EXTERNAL_DNS() should be used per domain. If you call it multiple times, the last prefix wins. If you have multiple external-dns instances with different prefixes managing the same zone, use IGNORE() patterns for additional prefixes.
TXT Registry Format
This feature relies on external-dns's TXT registry, which is the default registry type. The TXT record content format is well-documented:
"heritage=external-dns,external-dns/owner=<owner-id>,external-dns/resource=<resource>"This feature detects the heritage=external-dns marker in TXT records to identify external-dns managed records.
Custom Prefix Support
This feature supports custom prefixes configured via external-dns's --txt-prefix flag. If you're using a custom prefix, pass it to IGNORE_EXTERNAL_DNS():
// If external-dns uses --txt-prefix="extdns-"
IGNORE_EXTERNAL_DNS("extdns-")
// If external-dns uses --txt-prefix="myprefix-%{record_type}-"
IGNORE_EXTERNAL_DNS("myprefix-") // The record type part is handled automatically
// If external-dns uses --txt-prefix="extdns-%{record_type}." (period format)
// This is recommended for apex domain support per external-dns docs
IGNORE_EXTERNAL_DNS("extdns-") // Works with both hyphen and period formatWithout a prefix argument, it detects:
Default format:
%{record_type}-prefix (e.g.,a-,cname-)Legacy format: Same name as managed record (no prefix)
Period Format for Apex Domains
If you need external-dns to manage apex (root) domain records, the external-dns documentation recommends using a prefix with %{record_type} followed by a period:
# external-dns deployment args
args:
- --txt-prefix=extdns-%{record_type}.This creates TXT records like extdns-a.www for the www A record, and extdns-a for the apex A record. DNSControl's IGNORE_EXTERNAL_DNS supports both formats:
Hyphen format:
extdns-a-www(from--txt-prefix=extdns-with default%{record_type}-)Period format:
extdns-a.www(from--txt-prefix=extdns-%{record_type}.)
Note: Suffix-based naming (--txt-suffix) is not currently supported.
Unsupported Registries
External-dns supports multiple registry types. This feature only supports:
✅ TXT registry (default) - Stores metadata in TXT records
The following registries are not supported:
❌ DynamoDB registry - Stores metadata in AWS DynamoDB
❌ AWS-SD registry - Stores metadata in AWS Service Discovery
❌ noop registry - No metadata persistence
Legacy TXT Format
External-dns versions prior to v0.16 created TXT records without the record type prefix (e.g., myapp.example.com instead of a-myapp.example.com). This legacy format is supported but may match more records than intended since the record type cannot be determined.
See also
Last updated