A collection of task oriented solutions in Puppet

 

Installing packages with names that vary per distro

Challenge

You manage multiple operating systems or Linux distributions and sometimes they disagree on what a package should be named.

Solution

class apache_server {
  
    # determine the apache-server package based on the operatingsystem fact
    $apache_server = $::operatingsystem ? {
        Fedora  => 'httpd',
        default => 'apache2',
    }
  
    package { $apache_server:
        ensure => 'present',
        alias  => 'apache_server',
    }
  
    file { '/var/www/html/index.html':
        source  => 'puppet://modules/index.html',
        require => Package['apache_server'],
    }
  
}

Explanation

With the handy combination of a selector and a fact we can tailor the package name to suit the clients operating system. This construct takes the value of the '$operatingsystem' fact and compares it to the left hand value on each line of the body. If it matches one then the variable ($apache_server in this case) is set to the right hand side value of that line. If none match then the variable is set to the default value (apache2 in this case). You can also, using leaning toothpick style, use regular expressions (/Fedora|CentOS/) as the left-hand side.

If you need to subdivide versions of an operating system you can do so with facts like $lsbdistcodename (which on Debian for example will return etch, lenny or squeeze)

You'll also notice we have an alias line in the package resource. By explicitly setting an alias to this resource we can refer to it later, such as in the files require without needing to constantly use the variable. Is this a huge win? Probably not, but I like to reserve variables for places where things actually change a lot.