Short intro to Puppet

Puppet can be daunting at first. Here is a quick explanation of the most important elements I found useful when first being introduced to puppet.

Configuration Language

The configuration language reference can be currently found at http://docs.puppetlabs.com/puppet/2.7/reference/ and http://docs.puppetlabs.com/puppet/3/reference/index.html . There are several parts to the puppet language. What follows is a quick description of the items most useful to me: facter, certain directives, augeas, and stages.

Facter

Facter is a simple name value pair of configuration items. For example

swapfree => 0.00 kB
swapsize => 0.00 kB
timezone => Local time zone must be set--see zic manual page
uniqueid => d40a1a41
uptime => 37 days
uptime_days => 37
uptime_hours => 910
uptime_seconds => 3276155

There are a set of default facts you get when you install facter which are generally useful, cpu type, number of cpus, hypervisor info, OS type, etc. This catalogue of facts is used to identify the machine in your configuration management database. Additionally, these facts are all accessable as variables inside your puppet code.

Lastly regarding facter you can create custom facts. Custom facts are authored in ruby. You create a small ruby program that returns a string representing the answer to a complicated calculation. Every time puppet is run on this machine, the fact will be calculated.

Puppet Language Highlights

Puppet allows you to describe an intended system state. It does this by creating resources that represent the major pieces of a running OS. Packages, Services, Files, Users, Groups, Host, and Mounts are just some examples of resource types.

File

Typically you are looking at files to control a machines configuration. That said puppet gives you two main ways to deal with these configuration file, copy them wholesale from a repository or generate them from a template based on facts.

file {
"/etc/sshd/sshd_config" :
content => template("openssh/sshd_config.erb"),
require => Package["openssh"]
}

This statement will create an sshd_config file in /etc/sshd based on the template sshd_config.erb. The template files are plain text except for the variables. For example:

ListenAddress <%= ipaddress %>

This allows the puppet class to create a correct config file based on the current environment or facts pre-populated. Dynamically generating the configuration allows the system to be right for where ever it is.

Services

Services are system level programs that run in the background. Generally these are services in the microsoft world or daemons in the UNIX world. The Service resource is very similar to the file resource in structure.

service {
"syslog":
enable => "true",
ensure => "running",
hasstatus => "true",
require => File["syslog.conf"],
subscribe => File["syslog.conf"]
}
This makes syslog start at boot, run if its not currently running, is able to return status, has its config file, and will automatically restart if the config file changes. This class can be applied to a running system and have the changes reflected immediately and correctly. If this resource is constructed correctly, a service will know of all its dependencies and react accordingly.

Packages

Packages are how an OS manages an installable feature. In UNIX land typically this refers to the RPM manager, yum, yast etc. In Gentoo its the emerge system and ebuilds, in the microsoft world this is the package installers.

 

Above is an example of puppet installing a package.

Augeas

While Augeas is technically a resource type, its a quite complicated way of manipulating configuration files. Basically, augeas hold a grammar for each config file you may be interested in, httpd.conf, sshd_config, etc. Augeas loads the parse tree into memory and allows you to manipulate the parse tree to add syntactically correct  statements. For example, you can insert changes in one fell swoop in a php.ini file without any complicated text manipulation.


augeas {
"php.ini":
notify => Service[httpd],
require => Package[php],
context => "/files/etc/php.ini/PHP",
changes => [
"set post_max_size 10M",
"set upload_max_filesize 10M",
];
}

This changes just those two values in the file without any sed or perl magic. This can be applied to more complicated objects like httpd.conf virtual hosts and other directives. Augeas is the most reliable way to change a file you don’t want to templateize.