Skip to content

MCP for AI agents30 toolsYour AI agent works with the rights you give it. Registering, transferring and cancelling stay in the customer area. If you give it the right, it can retrieve the transfer code of a domain: at most 3 retrievals per domain and day, and every retrieval is logged.

Read the MCP docs
Recipe
about 15 minutes
v1.6.2
Download OpenAPI

Apply DNS desired state to a zone

Compare the current record set of a zone with the intended target state and synchronize missing, changed, and obsolete entries.
Advancedabout 15 minutesDNSZoneSyncDriftAutomation
Duration
about 15 minutes
Level
Advanced
Endpoints
4

This recipe enforces a defined DNS desired state against an existing zone. You first read the current state, compare it with your target definition, and then perform focused create, update, and delete operations.

There is also a small Bash example script for this workflow: dns-desired-state-sync-example.sh. The script reads the desired state from a JSON file and prints an example of the expected file format when started without arguments.

Prerequisites

  • an API key with access to the DNS endpoints
  • an existing zone managed through regfish DNS
  • an internal desired-state definition, for example from Git, Terraform, or your own service config
  • a clear rule that defines which records may be managed automatically and which may not

Step 1: Read the current zone state

Every sync starts with a full snapshot of the zone. What matters here is that you capture not only name, type, and data, but also the id so updates and deletes remain unambiguous.

bash
curl --request GET \
  --url 'https://api.regfish.com/dns/example.com/rr' \
  --header 'x-api-key: YOUR_API_KEY'

You will typically receive a list of records including their IDs:

json
{
  "success": true,
  "response": [
    {
      "id": 101,
      "type": "A",
      "name": "api.example.com.",
      "data": "203.0.113.10"
    },
    {
      "id": 102,
      "type": "CNAME",
      "name": "www.example.com.",
      "data": "example.com."
    }
  ]
}

Step 2: Define the desired state internally

Prepare a target set for the synchronization job. In many environments it comes from a file or deployment system. The important part is that you compare normalized values, for example with FQDNs consistently stored with a trailing dot.

json
[
  {
    "type": "A",
    "name": "api.example.com.",
    "data": "203.0.113.20",
    "ttl": 300,
    "annotation": "managed-by=dns-desired-state-sync-example"
  },
  {
    "type": "CNAME",
    "name": "www.example.com.",
    "data": "example.com.",
    "ttl": 300,
    "annotation": "managed-by=dns-desired-state-sync-example"
  },
  {
    "type": "TXT",
    "name": "_service.example.com.",
    "data": "managed-by=regfish-api",
    "ttl": 300,
    "annotation": "managed-by=dns-desired-state-sync-example"
  }
]

The script runs in dry-run mode by default and only applies changes when started with APPLY=1:

bash
curl -fsSLO 'https://www.regfish.de/downloads/docs/dns-desired-state-sync-example.sh'
chmod +x dns-desired-state-sync-example.sh
./dns-desired-state-sync-example.sh
API_KEY=YOUR_API_KEY DOMAIN=example.com ./dns-desired-state-sync-example.sh desired-state.json
APPLY=1 API_KEY=YOUR_API_KEY DOMAIN=example.com ./dns-desired-state-sync-example.sh desired-state.json

Step 3: Create missing records

Records that exist in the desired state but not in the current state are created from scratch. This is the simplest part of the reconciliation.

bash
curl --request POST \
  --url 'https://api.regfish.com/dns/rr' \
  --header 'content-type: application/json' \
  --header 'x-api-key: YOUR_API_KEY' \
  --data '
{
  "type": "TXT",
  "name": "_service.example.com.",
  "data": "managed-by=regfish-api",
  "ttl": 300,
  "annotation": "managed-by=dns-desired-state-sync-example"
}
'

Step 4: Update changed records by RRID

If a record already exists but data, ttl, or another relevant field has changed, update it by rrid. That avoids ambiguity when similar records exist.

bash
curl --request PATCH \
  --url 'https://api.regfish.com/dns/rr/101' \
  --header 'content-type: application/json' \
  --header 'x-api-key: YOUR_API_KEY' \
  --data '
{
  "type": "A",
  "name": "api",
  "data": "203.0.113.20",
  "ttl": 300,
  "annotation": "synced-by-desired-state-job"
}
'

Step 5: Remove obsolete records

Anything that still exists in the zone but no longer appears in the desired state is drift and can be removed. This is also the step where you should be strict about only deleting records that your workflow actually owns.

bash
curl --request DELETE \
  --url 'https://api.regfish.com/dns/rr/103' \
  --header 'x-api-key: YOUR_API_KEY'

Practical notes for production workflows

  • compare records by both name and type
  • normalize FQDNs and trailing dots before comparing
  • separate manually maintained records from automated ones through conventions or annotations
  • run a dry-run first and log planned changes before applying them
  • treat deletes more strictly than creates and updates, for example through allowlists

Result

This turns individual DNS endpoints into an idempotent sync workflow. That is what you need to reduce drift and derive repeatable changes from deployments or configuration state.

Community

Become part of the community

The regfish DNS API is a great solution for developers who want to automate domains and DNS zones. Become part of the community and benefit from DNS automation. The DNS API is available free of charge to every regfish customer.