You are on page 1of 7

An Introduction to Puppet

Robert Harker
harker at harker dot com




What Is Puppet
Puppet is a configuration management tool

Written by Luke Kanies
Supported by Puppet Labs (formerly Reductive Labs)
Client/Server model
Written in Ruby

Puppet Language
Puppet decouples the syntax of the configuration management tool from the syntax of the underlying
OS and applications

This allows you to define a high level idea like user, application, or service and puppet will translate
that in to the commands required by the client OS

Configuration information is specified in "recipes"

Recipe files end with .pp

The recipes define what the system should look like (be configured as)

Puppet then issues OS/applications specific commands to change the configuration to match the
desired result

Recipes are written in ruby

How Puppet Works
Puppet has a passive server called the "puppet master":

Runs the RPC­XML/HTTPS server listening on port 8140

Acts a the certificate authority for the puppet clients

Has recipes the clients can download

Has repositories of files the clients can download

Puppet clients pull configuration information from the puppet master

Client first collects local host configuration information using factor

Client then requests a master recipe to configure the client

pp You do not typically need to change the puppet.rpm I then use yum on the puppet master:   yum install puppet puppet‐server And on each client I install just the client:   yum install puppet Make sure the puppet user exists:   id puppet Creating a Simple Puppet Configuration The puppet master is configured in two places:   /etc/puppet/puppet.     group => "root:   } Type is file Title is /etc/hosts Attributes define the owner and group is root Installing Puppet I use RHEL/CentOS so I use the Fedora Project EPEL repository   rpm ‐ivh http://download.fedora. This master recipe then pulls in additional recipes based on the client's configuration The puppet client then translates this information into host specific commands to run Puppet is a Declarative Language Configuration components are organized into resources Resources are grouped into collections Resources are made up of a type.pp file is:   file { "/etc/hosts":     owner => "root".   } Running the Puppet Master .     group => "root".com/pub/epel/5/x86_64/epel‐release‐5‐3.noarch.conf file The site. title and a series of attributes:   file { "/etc/hosts":     owner => "root".     mode => "644".pp pulls in all of the puppet recipes The simplest site.redhat.conf   /etc/puppet/manifests/site.

The puppetmasterd runs only on the puppetmaster:   chkconfig puppetmasterd on   service puppetmasterd start Look for error in:   /var/log/puppet/masterhttp.log Running the Puppet client Normally the puppet client runs as a daemon You can run it manually   puppetd ‐v ‐‐test If we break the hosts file:   chmod 664 /etc/hosts And run puppet in verbose mode:   puppetd ‐v ‐‐no‐daemonize We should see:   notice: Starting Puppet client version 0..harker.harker. A class is defined with:   class Title {   } .25.5   info: Caching catalog for puppet. services.' }   # Set global defaults ‐ including backing up all files to the main   # filebucket and adds a global path   File { backup => main }   Exec { path => "/usr/bin:/usr/sbin/:/bin:/sbin" } Puppet Nodes and Classes Puppet has three types of recipe files: Nodes: host or node control (configuration) files Classes: action files that define what to do Modules: Reusable classes Puppet Classes Puppet classes define how to install and configure   info: Applying configuration version '1279238728'   notice: //sysfiles/File[/etc/hosts]/mode: mode changed '664' to '644'   notice: Finished catalog run in 0..pp File   import "classes"   import "modules"   import "nodes"   # The filebucket option allows for file backups to the server   filebucket { main: server => 'puppet.02 seconds Puppet Defaults In The site.kvm. applications.

    mode => "644".     }   } This class is then included in a node definition with:   include sysfiles The Nodes File The nodes defines what classes and modules are applied to which hosts Typically the node definitions are put in a node.pp file that includes the sysfiles class:   # /etc/puppet/manifests/nodes.pp   node default {     include sysfiles   } Nodes have inheritance A complex node can be configured by inheriting a simpler node I start with a basenode that all hosts inherit This includes things I want done on all nodes: Applications installed or removed Services enabled or disabled Site wide configuration files You can then make a more complex node based on this inheritance Webserver = basenode + apache MySQLserver = basenode + MySQL You can then make a specific node or host: fooMysql = MySQLserver + foo specific additions barMysql = MySQLserver + bar specific additions Two cautions: .pp   class sysfiles {     file { "/etc/hosts":     owner => "root".     group => "root".     mode => "644".     group => "root".     }     file { "/etc/passwd":     owner => "root". Resources are then added to the class A class can have multiple resources:   #/etc/puppet/manifests/classes/sysfiles.pp The default node is used if there is no match for a specific host A simple site.pp file:   /etc/puppet/nodes.

pp file:   mv /etc/puppet/manifests/classes/ntpd. templates and files that configures a particular application or function You typically make a modules sub­directory:   mkdir ‐p /etc/puppet/modules Then a sub­directory for each module   mkdir ‐p /etc/puppet/modules/sudo In a manifest sub­directory puppet related files get added:   mkdir ‐p /etc/puppet/modules/ntpd/manifests You would then add the ntpd. .].       source  => "puppet:///files/etc/ntp.   fudge 127. You can not redefine resources Once a resource is added it is very difficult to remove it A Class To Install an Application/Service   # /etc/puppet/manifests/classes/ntpd. File["/etc/ntp.       group   => root.       mode  => 444. configuration for ntpd   . .1.conf":       owner   => root.       backup => false.conf.       require => Package["ntp"].conf:   # /etc/ntp.conf"].127.     }     service { "ntpd":       enable => true . configuration resources.pp /etc/puppet/modules/ntpd/manifests/ntpd.pp You can also have a module install files:   /etc/puppet/modules/ntpd/files Puppet Templates Modules can also edit files on the fly:   /etc/puppet/modules/ntpd/templates In /etc/puppet/modules/ntpd/templates/ntp.pp   class ntp {     package { ntp: ensure => present }     file { "/etc/ntp. .       subscribe => [Package[ntp].       ensure => running.     }   } Puppet Modules A puppet module is a portable collection of classes. .conf". .0 stratum <%= local_stratum %>   .

 . .conf":     content => template("ntp/ntp. you can no longer use puppet to rebuild the box if the server crashes..   }   . .conf The ntp.     default => $ntp_local_stratum. Some Pontificating: Why I dislike Kickstart/Jumpstart Both are one time tools They lock a lot of configuration choices into their config files You can't rerun them without reinstalling the system The real problem: OK. . Lay out partitions so the box can be rebuilt: OS on one partition Data directories on a separate partition Logs if critical on a third Rebuild your servers periodically This is painful the first dozen times because people cheat By doing this regularly.  includefile /etc/ntp.client.server.conf   includefile /etc/ntp. then so time later in an emergency you ssh to the box and make a change.   }   config_file { "/etc/ntp. If you are going to maintain the system with a tool after you kickstart the server then why don't you simply use that tool for all of the configuration after a minimal core kickstart install? Periodically rebuilding servers: One of the problems with configuration management systems is that they are not always used You deploy the server with puppet. I have kickstarted the system.   $local_stratum = $ntp_local_stratum ? {     '' => 13.pp recipe file:   . Now I want to: Add an additional package Change a config file Add a user And the answer is: We then run [ssh|script|rsync|cfengine|puppet]. it keeps you honest The wrong time to discover that puppet can not rebuild your server is not after that server has crashed .     require => Package[$ntp_package]. Unless you update the puppet configuration..conf").

. different patches Development and staging may have additional requirements than production. different libraries. different kernel versions.  Add them to the puppet configuration Rebuild Staging and development build/test servers before each (major?) code deploy. Much easier to do it in a planned maintenance window Use puppet in all of your environments Production Staging Development build/test By giving developers and staging the same environment as production you avoid gremlins like missing packages.