Automating DNS Records with Ansible – Dynamic A and PTR Records from JSON

Managing DNS entries manually can quickly become error-prone, especially in labs, test environments, or dynamic infrastructures where hosts and IP addresses change frequently. Automation with Ansible helps keep DNS zones consistent, saves time, and reduces mistakes.

In this post, I’ll show how to create A and PTR records automatically from a simple JSON file, including dynamically generating reverse zones directly from IP addresses.


The Challenge

We want to:

  • Ensure that a forward zone (e.g., test.lab) exists.
  • Add A records for each host.
  • Automatically generate PTR records in the appropriate reverse zones.
  • Create reverse zones dynamically from the host IPs, so no manual reverse zone management is needed.

JSON as the Source of Truth

All host data is stored in a JSON file:

{
  "forward_zone": "test.lab",
  "records": [
    {
      "name": "node1",
      "ip": "10.0.5.11"
    },
    {
      "name": "node2",
      "ip": "10.0.5.12"
    }
  ]
}

This makes adding or removing records as simple as editing JSON.


The Ansible Playbook

---
- name: Manage DNS records from JSON
  hosts: windows_dns
  gather_facts: no
  vars_files:
    - records.json

  tasks:
    - name: Ensure forward zone exists
      community.windows.win_dns_zone:
        name: "{{ forward_zone }}"
        type: Primary
        replication: Domain
        state: present

    - name: Ensure reverse zone exists dynamically per record
      community.windows.win_dns_zone:
        name: "{{ '.'.join(item.ip.split('.')[-2::-1]) }}.in-addr.arpa"
        type: Primary
        replication: Domain
        state: present
      loop: "{{ records }}"
      loop_control:
        label: "{{ item.ip }}"

    - name: Ensure A records exist in forward zone
      community.windows.win_dns_record:
        name: "{{ item.name }}"
        type: "A"
        zone: "{{ forward_zone }}"
        value: "{{ item.ip }}"
        state: present
      loop: "{{ records }}"

    - name: Ensure PTR records exist in reverse zone
      community.windows.win_dns_record:
        name: "{{ item.ip.split('.')[-1] }}"
        type: "PTR"
        zone: "{{ '.'.join(item.ip.split('.')[-2::-1]) }}.in-addr.arpa"
        value: "{{ item.name }}.{{ forward_zone }}"
        state: present
      loop: "{{ records }}"
      loop_control:
        label: "{{ item.ip }}"

How the Reverse Zone Calculation Works

For an IP like 10.0.5.11:

  • Split into parts → ['10','0','5','11']
  • Take the first three octets reversed → ['5','0','10']
  • Join into a string → 5.0.10
  • Add suffix .in-addr.arpa5.0.10.in-addr.arpa

This means each PTR record automatically lands in the correct reverse zone without manual configuration.


Why This Helps

Automated and idempotent – Ansible ensures zones and records exist only once.
Centralized JSON – Easy to add or remove hosts.
Dynamic reverse zones – No need to manually maintain reverse DNS.
Consistent DNS – Forward and reverse zones always stay in sync.


Conclusion

With just a small JSON file and an Ansible playbook, you can fully automate DNS record management in Windows environments. This is especially powerful for labs, homelabs, or test environments where IP addresses change often.

DNS management becomes simple, reproducible, and reliable – exactly how automation should be.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert