Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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.

share|improve this answer
    
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? –  Alexandr Kurilin Jun 17 '13 at 21:06
    
In your example, where and when do you set the custom fact in the instance creation process? –  Alexandr Kurilin Jun 17 '13 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 '13 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 '13 at 15:04

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

share|improve this answer
    
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 –  Moataz Elmasry Sep 11 '14 at 15:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.