3

I'm writing an External Node Classifier for my Puppet infrastructure, and I have the need to manipulate the /etc/hosts file on each node. The following (due to the duplicate key) is invalid YAML:

---
  host:
    name: www1.example.com
    host_aliases: www1
    ip: 1.2.3.4
  host:
    name: www2.example.com
    host_aliases: www2
    ip: 1.2.3.5

I see this related answer, which has the following code:

host {
  # Public IPs - eth0
  'front-01': ip => '192.168.1.103';
  'front-02': ip => '192.168.1.106';

  # Private IPs - eth1
  'priv0-0': ip => '192.169.40.201';
  'priv0-1': ip => '192.169.40.202';
  'priv1-0': ip => '192.169.40.207';
  'priv1-1': ip => '192.169.40.208';

  # Virtual IPs - eth0:1
  'vip-01': ip => '192.169.50.202';
  'vip-02': ip => '192.169.50.205';
}

However,

  1. It's not immediately obvious to me what's actually going on here.
  2. I can't find documentation for this anywhere.
  3. Because these (don't look like) class parameters - and because of #1 and #2 above - it's also not obvious to me how I could translate this into YAML.

A naive guess would be:

'host':
  'www1':
    'ip': 1.2.3.4
  'www2':
    'ip': 1.2.3.5

But because of #2 above, I'm not comfortable moving forward with this in production. My question then:

Where can I find documentation on using the host class this way?

Or failing that

How else can I manage multiple /etc/hosts entries with an ENC?

NB: These definitions are being used to quickly configure transient multi-node clusters on a cloud services API for development and testing purposes, so while I'm not wholly unwilling to explore a DNS-based (or other alternative) solution, managing /etc/hosts in this way (if possible) is a much simpler solution with far fewer moving parts.


SOLUTION: Posted here for reference is my final code:

class my_hosts(
  $hosts = {
    'localhost.localdomain' => {
      'ensure'       => 'present',
      'name'         => 'localhost.localdomain',
      'host_aliases' => 'localhost',
      'ip'           => '127.0.0.1',
    },
  },
  ) {

  create_resources host, $hosts

}

And then my ENC YAML looks like this:

classes:
  my_hosts:
    hosts:
      www1.example.com:
        ensure: present
        name: www1.example.com
        host_aliases: www1
        ip: 10.0.0.101
      www2.example.com:
        ensure: present
        name: www2.example.com
        host_aliases: www2
        ip: 10.0.0.102
Chris Tonkinson
  • 465
  • 2
  • 6
  • 18
  • 1
    Managing a DNS zone with something like concat isn't any more difficult than managing the /etc/hosts file. I'm not sure why you're trying to avoid it. – Michael Hampton Feb 28 '14 at 15:42
  • Managing a DNS service is Yet Another Moving Part, whereas I'm already touching `/etc/hosts` so if there's a clean answer it makes a lot of sense. As I've said, the managed nodes are very transient (surviving on the order of minutes) for testing and deployment purposes - maintaining a DNS service seems like overkill if (keyword "if") I can simply manipulate `/etc/hosts` as I've described. – Chris Tonkinson Mar 02 '14 at 16:32

1 Answers1

5

ad 1 & 2:

host {
  'front-01': ip => '192.168.1.103';
  'front-02': ip => '192.168.1.106';
}

is just a shortened notation for

host { 'front-01':
  ip => '192.168.1.103',
}
host { 'front-02':
  ip => '192.168.1.106',
}

ad 3:

When you have a YAML data entry like this:

custom_hosts:
  www1:
    ip: 1.2.3.4
  www2:
    ip: 1.2.3.5
    comment: other attributes work also
  www3:
    name: testserver
    ip: 1.2.3.6

you can load it into a puppet hash and then create resources from it

$custom_hosts = hiera('custom_hosts',{})
create_resources(host, $custom_hosts)

This yields the same result as:

host { 'www1':
  ip => '1.2.3.4',
}
host { 'www2':
  ip      => '1.2.3.5',
  comment => 'other attributes work also',
}
host { 'www3':
  name => 'testserver',
  ip   => '1.2.3.6',
}

So these lines should be written to /etc/hosts:

1.2.3.4 www1
1.2.3.5 www2 # other attributes work also
1.2.3.6 testserver
mschuett
  • 3,066
  • 20
  • 21
  • I see, so this [`create_resources`](http://docs.puppetlabs.com/references/latest/function.html#createresources) function is a way to DRY out the name of a Puppet Type when you have multiple definitions for that type, is that correct? – Chris Tonkinson Mar 07 '14 at 20:31
  • So far I have only seen and used `create_resources` in combination with Hiera or ENC. -- For "hard-coded" resource collection the shortened notation in my first code example is DRY enough (and still readable without external data source). – mschuett Mar 07 '14 at 20:57
  • Fantastic - I have confirmed this works for my setup. Thanks! – Chris Tonkinson Mar 11 '14 at 13:03