0

I'm trying to find a simple and elegant way of having puppet identify what kind of node it's working with in EC2. For simplicity, let's say I have 3 node types: web, api and db.

Now, the very simplest way would be to make the node names in the puppet manifest be equal to the random hostname that Amazon gives them such as:

node 'domU-12-12-12-12-12-AB' inherits 'common' {
  #you're a web instance
}
node 'domU-13-13-13-13-13-AC' inherits 'common' {
  #you're an api instance
}
node 'domU-14-14-14-14-14-AD' inherits 'common' {
  #you're a db instance
}

However this has the downside of trashing source control with node renames every time you add or shut down an instance and its natural hostname changes. The other downside is that the hostname changes and so the puppet node manifest would have to be patched up every single time.

One route that you often hear proposed is that of editing /etc/hosts and /etc/hostname to something like "web1" and then use a regex in the puppet node statement. The problem is that once again the private IP changes and thus you need to update /etc/hosts, so this is a big headache. You also now need to map the real Amazon-given hostname to the one you just gave to the instance, an additional headache. I read that cloud-init is a solution to this, but I haven't played around with it much.

I'm trying hard to avoid additional overhead / steps in the process that might be fragile and break, so I'm looking for a solution to the above that's first of all simple.

What would you recommend?

2 Answers 2

3

The recommended way to do this would be to classify your nodes using a custom fact.

You can use a nodes.pp like this:

node default {
  hiera_include('classes')
}

node /.*some.domain.com$/ inherits default {
}

This way, you can use hiera.yaml to easily assign modules while keeping the common modules in another yaml file. This could be an example:

---
:backends:
  - yaml
:hierarchy:
  - "%{::hostname}"
  - common
:yaml:
  :datadir: "/etc/puppet/hieradata/%{::domain}/%{::location}"

Where the location fact is defined in /etc/facter/facts.d/datacenter.yaml file, which can also have more facts, if needed:

---
location: rohan

The resulting directory structure for your hieradata could look like:


$ tree
.
├── hiera.yaml
└── some.domain.com
    ├── rohan
    │   ├── common.yaml
    │   ├── host.specific.yaml
    │   └── other.host.yaml
    └── mordor
        ├── common.yaml
        ├── some.host.yaml
        └── other.host.yaml

Some more ideas regarding the use of hiera to classify nodes can be found here.

4
  • The one thing I'm not fully following is how an EC2 gets to acquire its identity. If I'm understanding this correctly, it's just an amorphous instance whose only unique property are its two private/public IPs. How do I tell such a nameless instance that it will, for example, belong to category x? Jun 17, 2013 at 21:06
  • In your example, where and when do you set the custom fact in the instance creation process? Jun 17, 2013 at 21:19
  • I define my custom facts when I kickstart my VMs. In your case, you need to define what's the most appropriate step in your provisioning flow to setup custom facts, be it custom images or any other process. Puppet includes functionality to help with cloud provisioning.
    – dawud
    Jun 18, 2013 at 6:25
  • Using node with a regex is really hard to scale. Use node default with hiera_include, and then do all of the classification in hiera.
    – robbyt
    Jun 18, 2013 at 15:04
1

Don't use node to classify machines. Write a "role" fact to /etc/facter/facts.d/role.txt. Use the ec2 instance ID as the puppet certificate name. Use hiera's hiera_include to assign modules based on the role fact of your nodes.

Here is a slide deck of a presentation I did last year on the topic. https://speakerdeck.com/robbyt/puppetcamp-nyc-2012-puppet-in-the-cloud

1
  • It is impossible to use the instance ids in a dynamic environment, since you have instances getting created and terminated all the time, and not just a set of static instances. In this case you need to define them into classes/categories and write your facter or something based on that Sep 11, 2014 at 15:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .