Quick start – Using the core Puppet resource types

(For more resources related to this topic, see here.)

Enabling the Puppet service

At this point in the process, it would be essential for me to tell you how to ensure that Puppet runs after reboot. It would be chkconfig on the RHEL systems, or update-rc.d on Debian, or smf on Solaris. But hey, why don't we use Puppet itself and let you see how Puppet saves you time and effort?

Use your favorite editor to edit/etc/puppet/manifests/site.pp. Add the following code:

node default {
service { 'puppet':
ensure => running,
enable => true,

/etc/puppet/manifests/site.pp is the one and only filename known by the Puppet server. All other files will be sourced or named from this file. I refer to this file as the origin of the Puppet policy.

ensure => running means that the Puppet agent daemon should be running. This might sound like a catch-22, but it's not really. You can run the Puppet agent manually (we will do this throughout the book.) This service resource ensures that the daemon is running, and starts it if it is not.

enable => true ensures that the process is configured to start up at boot time. This means different things on different platforms, but Puppet allows us to not focus on those details.

Now go to a client node and run the following command. You will see it apply this policy to the system:

$ sudo puppet agent –-test

You will get the following response:

Info: Retrieving plugin
Info: Caching catalog for myhost.example.net
Info: Applying configuration version '1357518358'
Notice: /Stage[main]//Node[default]/Service[puppet]/ensure: ensure
changed 'stopped' to 'running'
Notice: Finished catalog run in 0.95 seconds

If you want to stop the Puppet daemon, you could easily change the policy to the following code. During the next Puppet run it will disable the service and stop the daemon:

service { 'puppet':
ensure => stopped,
enable => false,

Let's stop for a moment and talk about the catalog, which is mentioned in the second line of preceding output. The catalog is a distilled, compiled version of the Puppet policy which contains only those directives necessary for the client node.

Obviously our previously mentioned test policy would apply to every node, so they would receive very similar catalogs. We will show you how to differentiate the policy given to each node in step 3.

Step 2 – Managing software and services

You can't start services if their packages aren't installed. So why don't we tweak the default node and add a little bit more code? The following segment ensures that the Puppet package is installed, and is the latest version. If the Puppet package is updated, the Puppet service will restart itself to get the new version:

package { 'puppet':
ensure => latest,
notify => Service['puppet'],
service { 'puppet':
ensure => running,
enable => true,
subscribe => Package['puppet'],

Notice how easy it is to set up dependencies between items? notify and subscribe are actually redundant here. You only need one or the other to build the linkage between these two resources. But if you're a belt-and-suspenders kind of person, it never hurts to list the dependency in both the places.

We have introduced another important concept here. By default, declarations in the Puppet policy can happen in any order. You use statements like require, before, notify, and subscribe to define dependencies that ensure that resources are applied in the appropriate order. We will cover ordering and dependencies in the next section.

Step 3 – Customizing one node

Now let's go a little further and customize the policy for one node. In the following section, we are going to ensure that the Puppet server is running the latest version of the Puppet master. Just below the default node block, let's add the following code:

node puppet-server-name inherits default {
package { 'puppet-server':
ensure => latest,
notify => Service['puppetmaster'],
service { 'puppetmaster':
ensure => running,
enable => true,
subscribe => Package['puppet-server'],

The inherits syntax of the node line says "do everything most nodes do, and also include this policy". You could leave off inherits default and the node would only execute the policy specifically within the node block. In this step we have now customized the catalog, which will be given to this one node.

The name you put in the node block is not the certname from the previous section, but the hostname of the box where the Puppet server is running. The Puppet server is really just the policy keeper. Policies are applied by the Puppet agent, even on the node which is running the server.

Step 4 – Synchronizing files and directories

Let's enable file synchronization down to the client node. First, we need to enable the file server. Use your favorite editor to edit /etc/puppet/fileserver.conf:

path /etc/puppet/files
allow *

Now let's create some test files for this example. We'll make the directory owned by you so that we don't have to sudo every command:

$ sudo mkdir /etc/puppet/files
$ sudo chown `id –u` /etc/puppet/files
$ cp /etc/hosts /etc/puppet/files/
$ cp /etc/motd /etc/puppet/files/

Now let's put some file resources here as examples. You can put the following policy text in the default node block (for all hosts), or you can put it inside a node block for a single host:

file { '/tmp/hosts':
ensure => file,
owner => nobody,
group => nobody,
mode => 0444,
force => false,
source => 'puppet:///files/hosts',
file { '/tmp/hosts.linked':
ensure => link,
target => '/tmp/hosts',
file { '/tmp/puppet-files':
ensure => directory,
owner => root,
group => root,
mode => 0444,
recurse => true,
source => 'puppet:///files',

Now let's test out the revised policy on your node:

$ sudo puppet agent --test

You will get the following response:

Info: Retrieving plugin
Info: Caching catalog for myhost.example.com
Info: Applying configuration version '1357520339'
Notice: /Stage[main]//Node[myhost]/File[/tmp/hosts]/ensure: defined
content as '{md5}41e6824ef17c17aa577cd6fd6f794351'
Notice: /Stage[main]//Node[myhost]/File[/tmp/hosts.linked]/ensure:
Notice: /Stage[main]//Node[myhost]/File[/tmp/puppet-files]/ensure:
Notice: /File[/tmp/puppet-files/hosts]/ensure: defined content as '{md5}4
Notice: /File[/tmp/puppet-files/motd]/ensure: defined content as '{md5}
Notice: Finished catalog run in 0.51 seconds

With a simple ls –la /tmp you'll be able to see the file, link, and directory that this policy has created.

At this point we've created a small but very effective Puppet policy. You have three different ways to copy files down to hosts. Packages are installed, and services are stopped or started based on your policy. And yet, the entire policy as expressed in the site.pp file, still fits on a single page. In this you can start to perceive the power of Puppet.


This article showed how to use the core resource types included within Puppet to reduce the amount of manual work and rework you do every day.

Resources for Article :

Further resources on this subject:

Books to Consider

comments powered by Disqus