Creating Dynamic Host Files With Chef

Maintaining host files on standard *nix system has been traditionally done by hand. This becomes a challenge as the number of systems grows and  is more true in the cloud model, where you might add/delete servers at a higher rate. One solution would be to use DNS and use a local zone to store your host name to IP mapping. If you are using Chef for automation, here is another example on how to automatically generate the host file entries.

Start by creating a cookbook:

knife create cookbook host_file_update

Then create the recipe:


hosts = search(:node, "*:*")
template "/etc/hosts" do
source "hosts.erb"
owner "root"
group "root"
mode 0644
    :hosts => hosts,
    :hostname => node[:hostname],
    :fqdn => node[:fqdn]

The above recipe uses this template file:

---   localhost  google_dns

<% @hosts.each do |node| %>
<%= node['ipaddress'] %> <%= node['hostname'] %> <%= node['fqdn'] %>
<% end %>

Since this is a regular Chef template file you can include static entries that you may want on all servers. For the remainder you loop through your search results and populate the host entries. Once you apply this recipe to all servers in your setup, every Chef run will automatically populate the host entries with the server names and IP.

This recipe does a search across all nodes in your environment. Note, you can modify the search to return certain nodes only. For example, you can limit it to production servers only. The same concept can be extended to a variety of other use cases. For example, adding servers to a load-balanced pool using the same search functionality.

search(:node, "chef_environment:_default")
search(:node, "role:webserver")

Search is quite powerful and you can read more at Chef Search.

This simple example demonstrates the power of infrastructure as code as you can take principles of programming and configuration management and apply it to system administration.

This post originally appeared on the Rackspace Developer Blog.

  • spencer owen

    I think you will want to add dashes to the erb template so it doesn’t create new line characters.