This content is part of the Essential Guide: The essential guide to open source virtualization platforms

Practice with Puppet examples to improve VM management

Learn the basics of VM management with Puppet by following these examples. Puppet is a powerful tool, and with practice, it can become an important asset.

Puppet is a sophisticated tool for pushing software, networks, storage configuration and applications onto a VM...

farm. By learning from the following Puppet examples, you can use it to better manage VMs.

The capabilities of Puppet

You can see what Puppet does at a glance by looking at the Puppet example below, which is included in the examples folder of the software.

This creates a file named /tmp/dansfile and writes "dan is awesome."

# This is a simple smoke test
# of the file_line resource type.
file { '/tmp/dansfile':
  ensure => file,
-> file_line { 'dans_line':
  line => 'dan is awesome',
  path => '/tmp/dansfile',

You can run this in one of two ways: the push model and the pull model. In the push model, you instruct the Puppet main server -- the name of which must be puppet -- to send configuration updates to all of the nodes. In the pull model, you can instruct the nodes to pull updates from the Puppet server at a set frequency.

In addition to Python, which can help admins manage VMs, Ruby on Rails can extend the usefulness of Puppet. With Puppet, you can use built-in and publicly sourced classes, resource definitions and your own Puppet code, but with Ruby on Rails, you can create all of that yourself.

Get started with a simple Puppet example

We need two VMs to begin, and because this is a master/slave architecture, we will call one puppet and the other slave.

To make Secure Shell work between machines, use the SSH-gen, and authorized_keys approach. With this, Puppet can issue commands across the network without requiring a password.

You also need to give the Puppet user the ability to run sudo without requiring a password. Run visudo on the nodes, and enter something like the following:

# User privilege specification
root    ALL=(ALL:ALL) ALL
walker ALL=(ALL) NOPASSWD:ALL   (some command)

You should restrict this to some specific command or else a hacker who gains access to a single server in your network could get root access to all of them.

Note that Puppet will run with as little as 5 MB of memory, but the default is 2 GB. When you install it with less, you need to reduce its Java memory requirements from the default in file/etc/default/puppetserver.

JAVA_ARGS="-Xms512m -Xmx512m -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"

Install the Puppet server

On the master named puppet, you need to add the Puppet repository as follows:

sudo dpkg -i puppet5-release-xenial.deb
sudo apt update

Install the Puppet server, and start:

apt-get install puppetserver
service puppetserver start

This installs the server, a Java Development Kit and the Puppet command-line interface.

The agent installation is as follows:

sudo dpkg -i puppet5-release-xenial.deb
sudo apt update
sudo apt-get install puppet-agent

Start it with the following input:

/opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true

On the master and agent updates, the user's account running Puppet must include /opt/puppetlabs/bin in the path.

When you start the agent, log in to the master, and run the command below to see if there's a node waiting for a server certificate:

puppet cert list
  "slave.lan" (SHA256) 7F:66:E6:71:72:37:00:AB:F0:C0:4E:CA:16:9A:6D:A0:25:CE:B9:A8:61:ED:AA:E2:D1:BC:99:EA:42:67:00:43

The name is slave.lan since we called our node slave. Sign the certificate like this:

puppet cert sign slave.lan

Signing Certificate Request for:
  "slave.lan" (SHA256) 7F:66:E6:71:72:37:00:AB:F0:C0:4E:CA:16:9A:6D:A0:25:CE:B9:A8:61:ED:AA:E2:D1:BC:99:EA:42:67:00:43
Notice: Signed certificate request for slave.lan
Notice: Removing file Puppet::SSL::CertificateRequest slave.lan at '/etc/puppetlabs/puppet/ssl/ca/requests/slave.lan.pem'

Run Puppet manifest

Let's run the Puppet example from above. It's in ./stdlib/examples/file_line.pp. To do so, you can either apply it to the local machine or run it from the Puppet master.

With Puppet, you set up production, test and other environments. We'll run the code in the production folder because that's the default setup.

From the master:

ssh [email protected] sudo puppet apply /etc/puppetlabs/code/environments/production/manifests/file_line.pp

Or on the slave:

puppet apply ./stdlib/examples/file_line.pp
Notice: Compiled catalog for puppet.lan in environment production in 0.03 seconds
Notice: /Stage[main]/Main/File[/tmp/dansfile]/ensure: created
Notice: /Stage[main]/Main/File_line[dans_line]/ensure: created
Notice: Applied catalog in 0.14 seconds

Use Puppet classes and modules

After you practice these Puppet examples, you can do something more complicated, like install Apache Spark across a whole set of clusters using code that users contribute to the Puppet repository.

To install Apache Spark using the example in the Puppet repository, use:

puppet module install cesnet-spark

Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...
Notice: Downloading from ...
Notice: Installing -- do not interrupt ...
└─┬ cesnet-spark (v1.2.1)
  ├─┬ cesnet-hadoop (v2.4.3)
  │ └─┬ cesnet-hadoop_lib (v0.2.1)
  │   └── adrien-alternatives (v0.3.0)
  └── puppetlabs-stdlib (v4.20.0)

This will give you:

ls /etc/puppetlabs/code/environments/production/modules/
alternatives  hadoop  hadoop_lib  ntp  spark  stdlib

Before running this, you first need to edit the config files and tell Puppet whether you want to include the job history server, where to put the Hadoop file system, how many nodes to use, whether to use Yarn and so on.

A class is a block of Puppet code that administrators can save as modules for future use. An example, from the Puppet documentation, is:

class base::linux {
  file { '/etc/passwd':
    owner => 'root',
    group => 'root',
    mode  => '0644',
  file { '/etc/shadow':
    owner => 'root',
    group => 'root',
    mode  => '0440',

This is like a class in other programming languages with functions and the ability to override functions in the resource it extends. In this case, the base class extends the Linux resource. You can define parameters as needed because the class above takes none.

File and cron job are example resources Puppet has built in. You can install others from Puppet.

Next Steps

Puppet and Chef lead open source automation

Explore different Puppet configuration management tools

Puppet's future in configuration management is bright

Familiarize yourself with CA for configuration management

Dig Deeper on Open source virtualization