One day after giving a one-hour presentation on what Ansible is capable of, “colleagues” flocked into my office and wanted to see stuff happen, so I showed them each a few odds and ends, in particular how Ansible can template out configuration files. I don’t think I exaggerate when I say that I think I saw tears of joy come to somebody’s eyes. Lovely. Anyhow, just a few days later, I was asked to find a solution for managing the creation (and destruction) of a potential boatload of DNS zones on a rather large number of PowerDNS servers.
I whipped up an Ansible module to create, delete, and list master or slave zones on authoritative PowerDNS servers with enabled REST API.
Unfortunately I had to resort to using urllib2 instead of Requests because
I must not touch (i.e. install anything on) these machines. Thanks to James’ comment below, I use Ansible’s built-in
pdns_zone module is very new, but it seems to do its job.
Create a master zone
In order to create a master zone, I invoke the module like this:
The API then adds the following records to the records table:
I can specify options to control how the module connects to the API, but by default it obtains these settings from the
pdns.conf file. (See the module documentation.) Simultaenously, the comments table is also modified via the API (even though I’m still not quite understanding the use of this; maybe somebody can help me see that):
Peter gave me an interesting use-case for the per/RRset comments in PowerDNS: people can add, say, issue-tracking numbers to the records’ comment in order to document how a record came to exist respectively why it was updated. It’s an interesting use-case, but it doesn’t cater for deletions… ;-)
Create a slave zone
Setting up a slave zone is very similar; the API modifies the domains table and, as shown above, the comments table.
Deleting a zone requires specifying
action=delete, and it’s removed from the
back-end database. In the case of deletion of a master zone, all records
are purged with the zone proper.
We can use the module to enumerate zones and their types (a.k.a. “kind”). As a special case, when we list zones, we can specify a shell-like glob which will match on names of zones. Consider this Ansible playbook and the associated template:
The output produced looks like this:
I think the list function is very practical as it allows me to connect to an authoritative server via SSH to enumerate zones, then turn around towards a second authoritative slave server (also via SSH) and create corresponding slave zones. (This is what you’d probably typically do with the PowerDNS superslave capability.)
The diagram illustrates this: from our management console, we use Ansible via SSH to connect to one server, and use the obtained list of zones to create, via Ansible and the same module of course, appropriate slave zones on a second server. (If this doesn’t make terribly much sense to you, you have my full understanding; trust me: it must be done this way in this particular case, if only because the machines have SSH access only.)
The JSON which is returned in the list command looks like this, with kind forced to lower case:
If this has piqued your interest, I’ve made the code and a few examples available in the pdns_zone module repository.