Commit:
ca917b62635321a15d79f190225b7cff9acc1bc9Source updated: · Edit this page
Cloudflare DNS integration¶
Goal¶
Manage selected external Cloudflare DNS zones through RillDNS while retaining the same plan, explicit confirmation, optimistic concurrency, verification, and audit workflow used for native CoreDNS zones.
Cloudflare zones are provider-backed zones. They are not copied into the local CoreDNS zone directory and do not participate in NOTIFY or AXFR replication.
Ownership rule¶
Each DNS record has exactly one writer. Terraform may continue to manage the Cloudflare zone, DNSSEC, account settings, rules, and the API-token bootstrap, but records delegated to RillDNS must be removed from Terraform configuration and state. Terraform and RillDNS must not manage the same record.
The initial ownership boundary is a complete zone. Per-record ownership may be added later only if RillDNS can make that boundary explicit and auditable.
Configuration and credentials¶
Cloudflare zones are configured as an explicit allowlist of DNS names. RillDNS resolves each name to its Cloudflare zone ID through the Zones API and caches the result. It never exposes account-wide discovery through its API. This keeps the ownership boundary reviewable while avoiding manual zone-ID configuration.
The API token is read from a root-owned file. Start with Zone Read and DNS Read on only the configured zones. Add DNS Write only when mutation support is enabled. Never put the token in command-line arguments, logs, API responses, or repository files.
Data model¶
Native and external zones remain distinguishable:
Zone
├── backend: native
│ └── zone file -> CoreDNS -> NOTIFY/AXFR
└── backend: cloudflare
└── Cloudflare API -> read-back -> authoritative DNS verification
RillDNS presents records as RRsets even though Cloudflare assigns an ID to each
individual record. Provider-only attributes live alongside, rather than inside,
portable DNS data. Initial attributes are proxied, comment, and tags.
Cloudflare's automatic TTL value (1) must remain distinct from a literal DNS
TTL.
A Cloudflare zone revision is a SHA-256 hash of its normalized record IDs, owners, types, contents, TTLs, and supported provider attributes. It is a synthetic optimistic-concurrency token, not a server-side Cloudflare ETag.
Read workflow¶
- Fetch every page of DNS records for the configured zone.
- Reject malformed or unexpectedly cross-zone records.
- Normalize names, types, content, ordering, and provider attributes.
- Group individual records into RRsets.
- Return the synthetic revision with the result.
Mutation workflow¶
- Read the current records and compare the requested revision.
- Validate the complete proposed record set and provider attributes.
- Produce a dry-run plan containing record-ID deletes, patches, puts, and creates.
- On
confirm=true, read and compare the revision again immediately before writing. - Submit one Cloudflare batch request.
- Read back until the API reflects the intended state.
- Query Cloudflare's authoritative nameservers until the public answers converge or the verification deadline expires.
- Append an audit event. If application or verification fails, attempt a compensating batch and report both the original and rollback outcomes.
Cloudflare executes a batch in a database transaction, but propagation through
its distributed DNS store is not atomic. Results must distinguish accepted,
api_verified, and dns_verified states.
API and MCP shape¶
The initial read-only surface is deliberately separate from native zones:
GET /v1/providers/cloudflare/zonesGET /v1/providers/cloudflare/zones/{zone}/recordsdns_cloudflare_list_zonesdns_cloudflare_list_records
Mutation tools will follow the existing two-step convention:
dns_cloudflare_plan_changesdns_cloudflare_apply_changeswith the exact revision andconfirm=true
Once behavior and migrations are proven, a unified zone-list view can be added without removing the provider-specific endpoints.
Delivery plan¶
- [x] Read-only client, normalization, pagination, revisions, and tests.
- [x] Explicit zone configuration and secret-file loading in
rill-api. - [x] Read-only REST endpoints and control client.
- [x] Read-only MCP tools and documentation.
- [x] Dry-run planner for A, AAAA, CNAME, TXT, MX, CAA, SRV, and NS records.
- [x] Batch apply with second revision check and API read-back verification.
- [x] Authoritative DNS verification, audit events, and compensating rollback.
- [x] Terraform migration report and operator runbook.
- [x] Web console record browsing, planning, and guarded application.
Non-goals for the first mutation release¶
- Cloudflare zone creation or deletion.
- DNSSEC, nameserver, account, rules, or proxy-setting administration outside record-level attributes.
- Account-wide zone discovery.
- Concurrent Terraform and RillDNS ownership of a record.
- A claim of globally atomic DNS propagation.