Friday, July 29, 2011

Puppet managing differences for multiple environments

*** EDIT ***
I have switched to using extlookup for dealing with my different environments.
************

I spent some time searching around for a way of dealing with a single source of puppet but using it in multiple different environments for mainly small differences. The generally suggested approach is to use your favorite version control system, but I didn't really want to pollute my version control with lots of difference that related to things like DNS servers and other environment specific things.
The solution that I eventually landed on was to put all of the variables that are truly different (there were not a lot, in the end less than 5) between the environments into a single statement for example:
include net.pp
if $network == "network1" {
$puppetserver = 'puppetnet1'
$nameservers = ['192.168.1.123']
...
}elsif $network == "network2" {
$puppetserver = 'puppetnet2'
$nameservers = ['192.168.2.123']
...
}
This can be placed where ever you want in your setup structure. For example it could go in the nodes.pp or site.pp file if you don't have a better spot for it. I had a separate params.pp already with some other stuff in there which made sense for me.
In a separate file called "net.pp" which I included in the above file I have one line which defines the network varirable, so:
net.pp
#Define what network this puppet master is serving. Valid values are network1, network2 or network3
$network=network2
I also created a file called net.pp.TEMPLATE (name is not important) that has the above file just without the network defined; this way when setting up a new puppet master or new puppet master environment from the source configuration I have a template to start with (otherwise you have to remember what net.pp is and what to put in it).
net.pp.TEMPLATE
#Define what network this puppetmaster is serving. Valid values are network1, network2 or network3
$network=
Finally the net.pp is set to be ignored by version control, for example using bzr:
bzr ignore net.pp
Now I don't have merge problems when moving changes between puppet masters, all the variables are versioned and can be edited at the same time instead of at deployment (to be fair this is both good and bad).
The main disadvantage of this approach is that there are these magic variables that seem to appear from nowhere in other areas. In the end however I was pretty happy with this approach, it was nothing ground breaking but allowed for a maintainable setup where I didn't have to deal with merges sprinkled through out the puppet config.