Managing Infrastructure with Puppet - James Loope [6]
* * *
Note
It’s a great habit to write your manifests to be as operating system independent as you can manage. Not only will it help make your system more versatile, but it will make it convenient for others in the community to reuse when you graciously contribute it back!
* * *
This begs the question: How does Puppet know what OS it’s running on? The answer lies with the facter command. Go ahead and execute facter --puppet and inspect the results. You’ll see that Facter knows a lot about your system configuration. Facter comes with a wide range of “facts” defined that describe all different parts of your system. To ascertain what OS it’s running on, Puppet uses the Facter library and looks up the $operatingsystem fact. These facts are also available to us in the manifests themselves. If we would rather make explicit decisions about what to do in different situations (like on different operating systems), we can do that with facts.
In this example, I’ve added a selector operation into the source parameter. This specifies that if the $operatingsystem fact is Ubuntu, we should use the source file at /mnt/nfs/configs/ubuntu-ntp.conf; else we should use the default source file. Classic if-else and case statements are also allowed:
package { 'ntp': ensure => '1:4.2.6.p2+dfsg-1ubuntu5' }
file { '/etc/ntp.conf':
mode => '640',
owner => root,
group => root,
source => $operatingsystem ? {
'Ubuntu' => '/mnt/nfs/configs/ubuntu-ntp.conf',
default => '/mnt/nfs/configs/default-ntp.conf',
},
require => Package[ntp],
}
service { "ntp":
ensure => running,
enable => true,
pattern => 'ntpd',
subscribe => [Package["ntp"], File["/etc/ntp.conf"]],
}
Here we’ve made a simple decision tree that prints out a notice depending on the OS type and version reported by Facter. Notices can be useful for logging of Puppet runs and reporting on exceptional conditions. Puppet can be very verbose about what changes it’s made, but custom logging is convenient:
if $operatingsystem == 'Ubuntu' {
case $operatingsystemrelease {
'11.04': { notice("Natty Narwahl") }
'10.10': { notice("Maverick Meerkat") }
'10.04': { notice("Lucid Lynx") }
}
} else {
notice("We're not on Ubuntu!")
}
With these basic tools alone, we have enough to begin writing some convenient system installation scripts. That would let us build up a big manifest full of resource declarations and decision structures and then apply them to a system with Puppet. This manual execution is useful for writing and testing Puppet manifests, but as we’ll see in the next chapter, we can let the servers configure themselves instead.
The Puppet Master
Running a central Puppet Master server will allow us to build configurations that are specific to a particular system and then hand them out to be executed on demand. It can be a central repository for the configuration of all servers in your data center, allowing for the centralized deployment of updates and applications.
Once the Puppet Master is installed, you’ll have an empty Puppet repository in /etc/puppet. When the Puppet Master starts up, the first file it loads is /etc/puppet/manifests/site.pp. Generally this file will include a nodes.pp file as well as set some default parameters. nodes.pp will tell the Puppet Master how to decide what classes it should apply to a system, called a node, when it checks in.
* * *