Problem solve Get help with specific problems with your technologies, process and projects.

Virtual host management: How to use Puppet on Red Hat Enterprise Linux 5

Make administration of your virtual hosts easier with Puppet, a centralized configuration management tool, on Red Hat Enterprise Linux 5 (RHEL 5). Learn how to install and configure this Ruby-based application, as well as mastering nodes.

Today, many IT managers handle environments with hundreds, if not thousands, of virtual hosts that all require management and administration. One way they can take huge strides toward mastering that domain is mastering Puppet, a centralized configuration management tool.

In this tip I'm going to demonstrate how to install Puppet, a Ruby-based configuration management tool, on Red Hat Enterprise Linux 5. The instructions should also be useful for installations on distributions such as SUSE Enterprise Linux, CentOS and others too.

There are many hassles that can be eliminated with centralized configuration management. For instance, making a minor modification, such as changing the IP address of a DNS server, can result in a cascading series of hundreds or thousands of changes across sites, networks and hosts. Also, making manual changes to hundreds of hosts is neither cost effective nor a good use of usually already limited system administrator time.

Many organizations already use tools like Puppet and cfengine to manage their hosts, and it is easy to expand this use to cover virtual hosts. If you don't already use a tool like Puppet, then you'll be pleasantly surprised by how easy it is to implement and configure a centralized solution that will allow you quickly and simply change the configuration of your hosts.

More Red Hat Enterprise Linux 5 tutorials:
Intrusion detection with Snort on Red Hat Enterprise Linux 5

Using YUM in RHEL5 for RPM systems

Puppet has a client-server model, with a server called puppetmasterd, that manipulates the network-connected puppets. Communications are authenticated by internally-generated, self-signed SSL certificates and are conducted over TCP port 8140.

Puppet can interpret and execute generic instructions, such as creating users or installing packages, and executes them in a manner that a target operating system will understand. Puppet currently 'interprets' administration instructions for operating systems like Red Hat Enterprise Linux, Solaris, Debian, CentOS, SUSE, Fedora, Ubuntu and Oracle Linux. It is also used to manage applications such as Apache, MySQL, Subversion, OpenVPN and importantly for administrators of virtual hosts, Xen 3. Puppet can also act as a file server, allowing you to deliver files and content to target hosts. For example, after you've created a virtual host to be used as a Web server you could populate that host with any required website content.

Installing Puppet on Red Hat Enterprise Linux 5

Let's start with installing Puppet. Puppet has some simple prerequisites: Ruby, the Ruby libraries and Facter, a Ruby-based tool designed to discover 'facts' about hosts. You should also install the ruby-rdoc package if you want to use the Puppet documentation). Facter can return information like operating system details, IP addresses and other facts about a selected host. Puppet uses Facter to query remote hosts and return facts it requires to manage them. Facter is also user-expandable and you can configure it to query 'facts' specific to your environment and applications. Ruby and its libraries should be readily available on host distributions; on Red Hat, installing the ruby and ruby-libs packages will provide the required functionality.

Facter, and Puppet itself, can be installed a number of ways. Both are available from Reductive Labs in the form of source, Ruby Gems, RPMs together with packages for Solaris, Debian, SUSE, OS X and Gentoo. There are also RPMs for Red Hat Enterprise Linux 4 and 5 available from Red Hat. I'm just going to download the required RPMs and installed them.

I'm going to start with installing our Puppet master server.

# wget
# wget
# wget
# rpm -Uvh facter-1.3.7-1.el5.noarch.rpm puppet-0.22.4-1.el5.noarch.rpm puppet-server-0.22.4-1.el5.noarch.rpm

Managing nodes in Puppet

Once the puppet master is installed, we need to do some basic configuration and then start the daemon. Puppet operates not by executing scripts but by applying what are called 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 files also contain the definition of each of the hosts to be managed, which Puppet calls 'nodes'.

Each puppet master server requires a master manifest, called a site manifest. The site manifest is stored in the file /etc/puppet/manifests/site.pp. You'll need to create this directory like so:

# mkdir /etc/puppet/manifests 

You can see an example of a site.pp file below.

class base_etc {
      file { "/etc/passwd": owner => root, group => root, mode => 644}
      file { "/etc/sudoers": owner => root, group => root, mode => 440}
node default {
        include base_etc

The site manifest file can contain all the instructions you want to use on your managed hosts or can import the contents of other files to enable you to better structure your configuration instructions. Take a look at this example:

import "nodes.pp"
import "classes/*"

The above configuration would import the file nodes.pp and all the files in the classes directory. All directories are assumed to be under the /etc/puppet/manifests directory. You can also use Ruby globbing to define files to import.

In our example, site.pp file, we've specified a class called base_etc. Classes are containers for sets of instructions. In this case, the container holds two instructions, both using the file resource that sets the ownership and permission of the /etc/passwd and /etc/sudoers files. The file resource allows you to create files and directories or specify their permissions and ownership.

The file resource is one of a number of resource types, including types that can manage cron entries, host entries, manage packages, start and stop services or manage users. Each of these resource types can have multiple implementations, called providers, where each provider resource is designed for a different system. For instance, there are multiple file resource providers to cater for file operations on Linux, Unix, Windows and other platforms. This is one of the great strengths of Puppet; a single configuration language that can be interpreted appropriately on multiple target hosts running on different platforms.

We've also defined a node called default. The default node is a special definition that allows you to define sets of instructions that are applied to all nodes except those explicitly defined in your configuration. This allows you to specify a baseline configuration to all nodes without having to specifically define all nodes. We can also define other nodes in here (or in another file and import them).

A typical node definition looks like:

node goldfish {
       include apache

node '' inherits default {
        include mysql

Nodes are defined either by their simple name or a fully qualified domain name. If you use the fully-qualified domain name, then it must be encapsulated in single quotation marks. In our example, both the goldfish and nodes have been defined. Each node uses the include statement to specify particular classes that apply to them, which in this case are the apache and mysql classes, respectively. We've also specified that the salmon host also inherits the configuration of the default node.

One of the better ways to manage your Puppet configuration is to store it in a Subversion repository to provide better change control and manageability. You can find information on managing Puppet configuration at the Reductive Labs wiki.

Starting and configuring Puppet

Once you've created your site.pp file you can start the puppermasterd daemon. The Puppet RPMs come with an init script for Puppet, but we're going to start it manually on the command line:

# /usr/bin/puppetmasterd --verbose 

The --verbose option tells the puppetmasterd not to daemonize and to output all logging messages on the command line. If you omit this option, Puppet will daemonize by default. The Puppet master listens on port 8140 (you'll need to ensure your clients have network connectivity and access through any firewalls to this port on your Puppet server). You can also change a variety of configuration options for your Puppet master daemon by editing the /etc/puppet/puppetmasterd.conf file. You can see a full list of options at the Puppet wiki.

Now you need to install Puppet on one of your client nodes. We also need to install Ruby and the Ruby libraries on the client node and then we need to download and install the Puppet and Facter RPMs.

# wget
# wget
# rpm -Uvh facter-1.3.7-1.el5.noarch.rpm puppet-0.22.4-1.el5.noarch.rpm

Next, we need to configure the puppet.conf configuration file to tell it about our Puppet master server. The puppet.conf file is installed into the /etc/puppet directory. You can see an example of this file below.

    vardir = /var/lib/puppet
    logdir = /var/log/puppet
    rundir = /var/run/puppet
    ssldir = $vardir/ssl

    classfile = $vardir/classes.txt
    localconfig = $vardir/localconfig
    server =

The only setting we need to change is the server option. We'll need to change this option to the name of the Puppet master server, in our case You can see a full list of the potential configuration variables.

Connecting nodes to their masters in Puppet

As I mentioned earlier in the tip, communication between node and master is secured with a self-signed certificate. The first step in connecting a node to the master is to start the Puppet client.

# /usr/bin/puppetd --test

The client will automatically generate a certificate and send it to the master, where you will need to sign it. The Puppet client will then exit. Now, we need to sign the certificate that has been generated. We do this using the puppetca binary on the Puppet master server.

# puppetca --list

The puppetca binary has two options, --list and --sign. The --list option will list all the certificates waiting to be signed. The --sign allows you to sign waiting certificates. We can sign our client certificate by specifying the host name of the client, like so:

# puppetca --sign

Once the certificate has been signed, we can then start the Puppet client,

# puppetd 

The Puppet client will automatically daemonize and there is an init script for the client. Once the Puppet client is running, it will connect to the defined server and any target configuration will be applied to the client.

From then on the configuration is regularly applied, by default every 30 minutes, if a change is detected (if the configuration is unchanged then Puppet will do nothing). You can also tell the server to "push" out any new updates if you want to make an immediate change. Additionally, you can conduct logged "dry runs" from the server that allow you to test the rollout of new configuration.


This introduction has just scraped the surface of the power of Puppet, particularly with regard to configuration. Puppet manifests, or 'recipes' as they are often called, can perform some very complex configuration tasks. Here are a variety of Puppet example recipes. You can also find some recipes for the Facter tool that will help you add to the data you can query with. You can also find extensive documentation at and you can get support via the Puppet mailing list, IRC channel and FAQ.

Next Steps

By taking a declarative approach to automation, IT teams can define the desired state of their machines and determine how they will be configured.

Dig Deeper on Linux servers

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.