4

I am trying to manage my /etc/hosts file with puppet, but I don't like the internal 'host' type, I'd like to use my own template if possible.

I have therefore defined a 'host' resource:

    # Basic hosts configuration
    class hosts {

    # Host resource
    define host (
        $address,
        $names
    ) {

    }

    Network::Hosts::Host {
        before   => File['/etc/hosts']
    }

    # Configure hosts file
    file {
        "/etc/hosts":
        ensure   => present,
        checksum => md5,
        owner    => root,
        group    => root,
        mode     => 0644,
        content  => template("network/hosts.erb"),
    }

In other places, I define host resources:

network::hosts::host { 'puppet.test.lan':
    address => '192.168.56.101',
    names => 'puppet',
}

I would like to include the list of the defined hosts in my template, but I don't know how to iterate over the resources and their properties. I tried using string concatenation, but couldn't make it work and was not very elegant.

How can I iterate over all my defined hosts and include them from the template?

jjmontes
  • 3,247
  • 2
  • 17
  • 27

2 Answers2

5

I'd look at the augeas library for managing the entries in your /etc/hosts file. It's a prerequisite for Puppet, so it's already installed. You may need to download an additional augeas package to gain access to the augtool command line utility. This is useful for testing before Puppet integration.

The hosts file entry an example listed on the main site: http://augeas.net/tour.html

or

http://honglus.blogspot.com/2012/01/augeas-quick-start.html

I suppose you could also distribute a standard hosts file and just modify the line that needs to be unique per host...

ewwhite
  • 194,921
  • 91
  • 434
  • 799
  • Thanks, I'll consider augeas for this, but I'd still like to be able to use the technique I described for other kind of resources, so being able to iterate over them from templates would be great. – jjmontes Mar 04 '12 at 02:18
  • It gets the job done *sometimes*, but there are cases when augeas doesn't work with the file or that it's just not the right approach. – Hendy Irawan Jun 07 '12 at 18:00
4

You could use R.I.Pienaar's puppet-concat module where you build a single file out of many smaller files or templates.

The define would then look something like this:

define host($address, $names) {
  concat::fragment{"hosts-$address":
    target  => "/etc/hosts",
    content => template("network/hosts_single.erb")
  }
}

The hosts_single.erb template would represent a single line in the file. You'd probably also add a fragment for a header too and set order => "01" to ensure it's at the top of the generated file (10 is the default).

Dominic Cleal
  • 3,120
  • 17
  • 16
  • 1
    Thanks! I knew about puppet-concat. I can't still believe that Puppet doesn't make the data model available for templates: I'd like to some logical operations more than simply concatenating fragments. – jjmontes Mar 04 '12 at 13:22
  • Agree on jjmontes... this seems to be a pretty common requirement. I got hit by it often too, and I resort to dirty quick fixes. :-( – Hendy Irawan Jun 07 '12 at 18:00