Friday, August 1, 2014

Puppet Manifests and operating system updates

This is a post about my opinion on how we should be using the params.pp pattern. It originated from review here.

This is what the code used to look like:

$ruby_bundler_package = 'ruby-bundler'

It worked great on precise. It still does. However, when trusty came out, the changed the name of the package to bundler. This broke the above puppet code.

The fix was simple:

# will install ruby-bundler for all Debian distros
# or for Ubuntu trusty
if ($::operatingsystem == 'Debian') or ($::lsbdistcodename == 'trusty') {
  $ruby_bundler_package = 'bundler'
else {
  $ruby_bundler_package = 'ruby-bundler'


This is made a little more complicated because it handles Debian in addition to Ubuntu nodes.

However, there is a better way:

# will install ruby-bundler for Ubuntu Precise
# and bundler for Debian or newer Ubuntu distros
if ($::lsbdistcodename == 'precise') {
  $ruby_bundler_package = 'ruby-bundler'
}else {
  $ruby_bundler_package = 'bundler'

Instead of adding those names to an ever expanding case statement, this special cases the precise machines. In addition to being shorter, this better future-proofs the code. Inevitably this will be run on Utopic or later Ubuntu versions, and using the trusty package name by default will automatically work on these newer versions.

Now, generally it is best practice in case statements to fail on default, using the else statement like this is a violation of the spirit of that rule. But if statements like this are common in params.pp and will save you time in the future.

You can ask yourself as a follow up, "where else did i special case the new version of the operatingsystem, instead of special casing the old version."