Puppetize everything or not?

Solution 1:

The degree to which you can puppetize an entire environment is dependent upon several variables:

  • The willingness of the automation staff to write automation for every. little. thing.
  • The cultural conditioning that allows "I'll just change this one thing, it's a one-off anyway" to turn into "I'll just change this one thing in this puppet manifest, and apply it now; it's just a one-off."
  • The degree of heterogenaity in an environment.

It is definitely possible to puppetize every ********** thing that can be puppetized, but getting there requires the right culture and buy-in from everyone that can touch a puppet-able device. Some devices are fundamentally hard to manage that way, things like workstations, and puppet is better as a staging tool than a configuration management engine.

Puppet is awesome when you're managing a fleet of VMs all doing largely the same thing. Total win, and not a lot of effort to get there.

On the other end of the spectrum you have what I had at my last job, which was 200+ servers providing 130 services and only a small group of them doing so with more than one machine. There are absolutely companies (and universities) that have puppeted that kind of thing, but it's a lot of effort and takes a lot of buy-in. It requires that the first step of your new-machine deploy process not be "Install OS", but "create manifests".

Ultimately its an effort vs efficiency cultural issue you'll have to solve among all of your IT staff.

Solution 2:

PUPPET ALL THE THINGS

Anything that's reasonably similar across all systems (or a subset of them), or that you can base a template off a fact you can get out of facter is fair game.

Things that are really unique you probably shouldn't bother, and should just serve the configs out of a filebucket.

What falls into either category is a decision we can't make without knowing your environment intimately, so that's for you to figure out.

Solution 3:

I think others have covered the why so I'll take a shot at the how. I think by understanding how someone might use Puppet to do what you want, it'll make the decision clearer.

Do the basic case first

Your Puppet module for Apache shouldn't do much by default. Install Apache, config it to a minimum standard, and start the service. Make this work on all distros you need to support.

Add flexibility second

We need to add vhosts. You'll end up with a system that can drop file or remove them from a set of conf.d or vhosts.d/ directories according to what you need. Same thing with enabling or configuring modules.

Use role or hostgroup classes to tie your building blocks together

I think the best way to use Puppet is to make sure it's additive. Using the examples above we should have a module that does

  1. Install Apache
  2. Set basic configs
  3. Add vhosts to apache
  4. Configure any extra settings
  5. Start Apache

Rather than overload our default Apache module to do exactly what we need for a particular host or group we should handle this is a role or hostgroup class.

class role::web_cust1 {
  include apache
  apache::vhost {'www.domain.com': }
  apache::vhost {'www.domain2.com': priority => '99', }
  include php
  include php-fpm
  include mysql
}

Again additive.

Put special cases in Hiera

I'm a big fan of letting Puppet's Hiera, think of it as a database for Puppet, store the special bits. If a certain host or hostgroup needs a special setting, first put a sane default into the module so that normal users don't need to know about it. Then insert data for those special hosts or hostgroups so Hiera can consume it pass it to Puppet as needed.

My use case is Listen port. Some servers have a Varnish or haproxy in front of them. By default the Puppet module has Apache use port 80, but if Hiera finds data it will override that default.