We host our very own DNS server (BIND) for various reasons, including the fact that we deploy and kill machines very often and that we sometimes need to load balance via DNS very quickly.

However, now that we have a good 60 servers, we're kind of having a hard time keeping track of all the records and we tend to do mistakes when editing our zone file. Nothing too bad just yet (we use some other DNS provider as a backup), but I'm looking for a better way than just manually editing the file.

Also, since it's breeze for us to deploy new instances with the infamous chef, doing this by hand is kind of what takes the most time! It would be interested if we could automate this. Anyone knows about this? What's a good practice to edit and maintain this zone file?


You can use Chef search to dynamically build zone files as templates with Chef using the discovered hostname/fqdn and ipaddress of the nodes.

hosts = search(:node, "*:*")

template '/path/to/zonefile' do
  source 'zonefile.erb'
  variables(:hosts => hosts)
  owner 'root'
  group 'root'
  mode 0644
end

And the template would iterate over the hosts variable passed, using the hostname, fqdn and ipaddress of each result in the search. Contrived example:

<% @hosts.each do |h| -%>
<%= h['fqdn'] %>. IN A <%= h['ipaddress'] %>
<% end -%>

I know this is a month old now, but I just finished setting up a bit of an automated system to manage this for us. It's comprised of a git repository that contains:

  1. All primary zones and config files.
  2. All secondary zones and config files.
  3. Build scripts for my secondary name server - Ubuntu 10.0.4LTS
  4. A very simple Capistrano recipe that can update both primary and secondary name servers.

When I want to make an update to my zone files - here's the process.

git pull #to make sure it's current.
#Open the zone file and edit.
git diff #verify the change is what I want.
git commit -a; git push
cap primary:update #that also sends a notify to my secondary who pulls down the new zone
cap secondary:update #if I'm just updating the secondary.

It works really easily - I don't have to login to a bunch of servers to do anything - and it's pretty easy to see what I'm changing.

Also - it gives me a good history of changes.

If you'd like a copy of the repo - just lemme know and I'll DM you.


It's a pain that comes with the power of text configuration. I find 60 zone files a small number to deal, unless you have to daily change them, but maybe you can get better served by a server that supports DNS data from a database (PostgreSQL, for example) like PowerDNS. That allows for you to create simple scripts/pages/apps to deal with data (you can even provide a frontend to customers).

You can even configure bind to be a slave to a server using SQL it will automatically load the zone information from the master.

As for best practices:

  • Keep the zone file clean of useless comments,
  • Enforce correct use of tabs/spaces
  • Use the domain names for the zone files
  • I use vim macros to edit multiple files, but you can do that with sed and other tools

Since I assume all your servers are defined in your chef configuration, how about simply generate your zone files using that data? No idea if chef has some internal functionality for this, yet it seems like something which should be relatively trivial to script. To keep things separate it might be an idea to delegate these "dynamic" servers into a zone of their own.

That being said, are you sure you want to use DNS for loadbalancing purposes?


Integrity validation scripts, which do things like verify the serial number has gone up, and SCM, perhaps with something like Subversion, or whatever the local preferred poison is, to have a history and ability to revert.

Once you have the data in something like svn, you can have tools which add/remove individual hosts, while still letting humans edit the zonefile.

Otherwise, there are various options for moving the data out of flat files and into databases. PowerDNS is one, the DLZ patches for Bind are another. I will note that in terms of performance, if these are publicly exposed zones, you probably want to keep the database-backed server as a hidden master and let AXFR/IXFR propagate changes to the public masters, which can run stock bind. For internal zones (corp.example.com) this is likely overkill.