Configuration Management: Introduction to Puppet

Creative Commons License priittammets
After years spent working with Cfengine, Luke Kanies decided to form the company Reductive Labs in 2005 and Puppet, a long time idea and quickly stabilizing prototype, was born. He describes it as an open-source, next-generation server automation tool. Configuration files (called manifests) are written declaratively, and there is a client/server model for distribution handling. The configuration library, however, is what really distinguishes Puppet from its predecessor.

For example, lets say you want to do some user management. While Cfengine requires you to know whether the system command is useradd or adduser, Puppet has a pre-defined class user mapped as a resource which you can instantiate and get down to the real business at hand. This resource abstraction layer covers all the basics including services, filesystems and even crontab listings. Puppet administrators are free to focus on the complexity of their configurations, rather than being forced to also handle the complexity of the differences between the operating systems.

How does it work

Installation is as easy as apt-get install puppet puppetmaster under Debian systems or yum puppet puppet-server for Fedora class machines. Puppet is client-server based, with a manifest server program called puppetmasterd and client puppetd. puppet can be run for one-time, cmdline tests before getting invoking the background daemon puppetd). The manifest files are hosted (along with any other configuration files) on the server instance running puppetmasterd. Communications are authenticated by internally-generated, self-signed SSL certificates and conducted by default over TCP port 8140. Because of this, you’ll have to run puppetca --generate on the server for each client host in your network. After this, the puppet clients will be able to fetch and execute the configuration manifests. Puppet configurations are idempotent, meaning they can safely be run multiple times.

Manifests

Once the puppet master is installed, we need to do some basic configuration and then start the daemon. Puppet clients operate not by executing scripts but by applying a manifests against target hosts. A manifest is a Puppet configuration document that describes the target configuration and the steps required to achieve it. Your manifest file also contains the definition of each of the hosts to be managed, which Puppet calls ‘nodes’. Each puppet master server requires a master site manifest at /etc/puppet/manifests/site.pp. Here’s a sample site.pp file which configures an Apache webserver and a MySQL database instance:


# verify owner & permissions
class base_etc {
    file { "/etc/passwd": owner => root, group => root, mode => 644}
    file { "/etc/sudoers": owner => root, group => root, mode => 440}
}
 
# install apache
class apache2 {
    # using the local package manager, install the reqd pkg
    package { "apache2": ensure => installed }
 
    service { "apache2":
        ensure => running,
        hasstatus => true,
        hasrestart => true,
        require => Package["apache2"],
    }
}
 
# install mysql server and set root passwd
class mysql-server {
    $password = "insert_password_here"
    package { "MySQL-client": ensure => installed }
    package { "MySQL-server": ensure => installed }
    package { "MySQL-shared": ensure => installed }
 
 
    exec { "Set MySQL server root password":
    subscribe => [ Package["MySQL-server"], Package["MySQL-client"], Package["MySQL-shared"] ],
    refreshonly => true,
    unless => "mysqladmin -uroot -p$password status",
    path => "/bin:/usr/bin",
    command => "mysqladmin -uroot password $password",
    }
}
 
# default node is applied by _all_ connecting puppet clients
node default {
    include base_etc
}
 
# specific config for host www01
node www01 {
    # load the corresponding class defined above
    include apache2
}
 
# specific config for db01 (FQDN surrounded with ticks)
node 'db01.example.com' inherits default {
    # load the corresponding class defined above
    include mysql-server
}

Facter

Puppet uses a handy utility called Facter, a Ruby-based tool designed to discover ‘facts’ about hosts. It returns information like operating system details, IP addresses, SSH keys and other facts. Facter is also user-expandable and you can configure it to query ‘facts’ specific to your environment and applications.

Resources & Articles

The primary design goal of Puppet is that armed with an expressive language supported by a powerful library you can easily write your own server automation applications in just a few lines of code. You can express the configuration of your entire network in one program capable of realizing the configuration. The fact that Puppet is open source allows it to be easily extended (with any contributions welcomed back into the main project by the community). For a lot more information about the capabilities of Puppet, take a look at the onsite documentation. The quickly growing community base has a nice set of recipes available for some common system configuration needs. Finally, be sure to have a look at Luke Kanies’s Puppet In-depth and Hands-on as presented at Velocity 2008 to get the straight dope right from the horse’s mouth!

One thought on “Configuration Management: Introduction to Puppet

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.