Puppet and the Ghetto DNS

25 11 2011

Suppose you have a small network of Linux servers powering your web site. You’re probably going to want a way of accessing the servers by hostname from one another — for example, so your web servers can find your database servers without resorting to hardcoding IP addresses in your Apache configuration. What’s the best way to do this?

DNS

Well, if you’re already hosting your own DNS servers, you can consider a split-horizon configuration, which is supported by major DNS daemons like BIND. But if you’re using your ISP’s DNS servers, for example, setting up your own DNS for this purpose seems like overkill (and a pain). Personally, I like to run as few services on my network as possible, just as a matter of principle.

Another option is to just add A records for each of your servers to your site’s public DNS zone. But adding private (RFC1918) IP addresses to the public DNS means that anyone who can operate dig can find a complete list of your servers and their private IP addresses. Some would argue that I’m advocating for security by obscurity, but I just can’t see the upside of unnecessarily exposing information about your internal network to the public. Also, while it’ll work, exposing RFC1918 IPs via the public DNS just seems icky.

Hosts file

The “lightweight” approach to the problem of hostname to IP address resolution is to just add entries to the /etc/hosts file on each server. Of course, this is completely unmaintainable if you have more than 2 or 3 servers.

Hosts file + Puppet = Ghetto DNS

But if you’re using Puppet to automate your server infrastructure, it turns out that exported resources offer a nice solution to this problem. You can create and deploy a simple Puppet module to each machine that exports a Host entry for itself, and then assembles a /etc/hosts file based on the Host entries exported by all the machines Puppet knows about:


class hosts {
 host { "localhost.localdomain":
 ip => "127.0.0.1",
 host_aliases => [ "localhost" ],
 ensure => present,
 }
 @@host { "$fqdn":
 ip => $ipaddress_eth1,
 host_aliases => [ $hostname ],
 ensure => present,
 }

Host <<| |>>
}

This “Ghetto DNS” setup can be just right if manually maintaining hosts files seems impractical, but running your own DNS seems like overkill.