Testing Puppet Code in the Puppet Playground

Good testing of Puppet code involves different approaches and techniques that can be complex and time consuming. You can test your manifests' syntax with puppet parser validate, verify their code style with puppet-lint, test modules logic and behaviour at catalog level with rspec-puppet, and check the actual effect of a Puppet run on dispensable virtual machines managed by a tool like Vagrant.

You might be a beginner to Puppet looking to test and play with Puppet code, or you might be an experienced Puppet user and modules author who needs to test modules on different operating systems. Either way, you ought to try Example42's Puppet Playground.

The Puppet Playground is essentially a Vagrant multi-VM environment for masterless Puppet provisioning, with some tools and defaults that ease quick and safe Puppet code playing and multi-OS testing of modules and toasters (appliances), based on librarian-puppet. To use it, you need Vagrant running on your (possibly smart) computer and follow the instructions below for a quick, easy and (hopefully) joyful way to play and work with Puppet. Let's get started.


Clone the GitHub repository to a work directory of your choice (here, it's puppet-playground):

    git clone https://github.com/example42/puppet-playground.git puppet-playground

Move into the newly created directory, from this point all commands are relative to this path:

    cd puppet-playground

What you have is a normal Vagrant multi VM environment:

    vagrant status

This is enough to play with Puppet in Masterless mode:
You can write your Puppet code in manifests/init.pp, and place your modules in the modules/ directory, or you can use the bundled ./play command, which eases common operations.

Work with modules

You have various alternatives on how to work with Puppet Forge modules in the Puppet Playground:

  1. If you want to quickly test Puppet resources without using modules just write your Puppet code in manifests/init.pp (see below).
  2. If you want to test modules from the Puppet Forge you can install them with:
        puppet module install   --modulepath modules/

    So, for example, to install Puppet Labs's apache module type:

        puppet module install   --modulepath modules/
  3. If you want to test the NextGen Example42, modules you can just type:
        ./play setup example42

    This initializes the modules dir with the Example42 NextGen modules directly cloned from GitHub.

  4. If you want to test your own modules just place them in the modules dir, one module per directory, as you would do in your puppet master.
  5. If you want to play with toasters, install librarian-puppet and use the play script (more details below)
        gem install librarian-puppet
        ./play status
        ./play list
        ./play install 

Vagrant usage

Whatever method you use to populate the modules' directory, you can test your Puppet code using Vagrant commands. First, review (if you want) the default Vagrantfile provided by puppet-playground. You will see a normal MultiVM setup with masterless Puppet integration.

    cat Vagrantfile

You can see the available VMs with:

    vagrant status

Expect an output like the one below:

Current VM states:

Test_Centos6_64          not created
Test_Ubuntu1204_64       not created
Test_Ubuntu1004_64       not created
Test_Ubuntu1004_32       not created
Test_Debian6_64          not created
Test_SuseLinux11_64      not created
Test_OpenSuse12_64       not created
ToFix_Solaris10_64       not created
ToFix_FreeBSD9_64        not created
ToFix_OpenBSD5_64        not created
ToFix_Centos5_64         not created
ToFix_Centos5_32         not created
ToFix_Centos4_64         not created
ToFix_Ubuntu1104_64      not created
ToFix_RedHat6_64         not created
ToFix_ScientificLinux6_64not created

Boxes with the Test_ prefix have successfully been tested on an updated Vagrant/VirtualBox installation, the ones with ToFix_ have had some problem for a smooth automated Puppet run. This list is going to be updated and corrected with time, hopefully with the help of the community.

You can run any of the provided Vagrant boxes with:

    vagrant up Test_Centos6_64

This may take some minutes, the first time you run it, to download the base box from the Internet.

Once created the VM, you can connect to it with:

    vagrant ssh Test_Centos6_64

Note that at the moment headless mode is disabled, so you'll see the VirtualBox console window pop up. If you encounter problems with ssh, you should be able to login with user 'vagrant' and password ‘vagrant’ and then sudo -s.

To exit from the shell on the VM

    vm# exit

To restart your VM:

    vagrant reload Test_Centos6_64

To destroy and rebuild from scratch:

    vagrant destroy Test_Centos6_64
    vagrant up Test_Centos6_64

Work with Puppet

Once you see that Vagrant is doing its job, you can start to play with Puppet code: edit the default Puppet manifest applied on the boxes:

    vi manifests/init.pp

This is your test playground: add resources, use modules, declare classes...
You can place simple resources like:

    file { 'motd':
      path    => '/etc/motd',
      content => 'Hi there',

Or use modules you’ve previously placed in the modules/ dir.

    class { 'wordpress':

Or whatever Puppet code you might want to apply.

If you need to provide custom files, the sanest approach is to place them in the templates directory of a custom "site" module (call it 'site' or however you want) and refer to it using the content parameter:

    file { 'motd':
      path    => '/etc/motd',
      content => template('site/motd'),

This will populate /etc/motd with the template placed in

To test your code's changes on a single node, you have two alternatives:

  1. From your host, in the puppet-playground directory:
        vagrant provision Test_Centos6_64
  2. From the VM you have created:
        vagrant ssh Test_Centos6_64

    Once you've logged in the VM, get the superpowers and run Puppet:

        vm# sudo -s
        vm# puppet apply -v --modulepath '/tmp/vagrant-puppet/modules-0' --pluginsync /tmp/vagrant-puppet/manifests/init.pp

You can also edit the manifests file both from your host or inside a VM:

  1. From your host (having your cwd in puppet-playground directory):
        vi manifests/init.pp
  2. From the VM (once connected via ssh):

        vm# sudo -s
        vm# cd /tmp/vagrant-puppet/
        vm# vi manifests/init.pp

    If you have more VMs active you can test your changes on all of them with a simple:

        vagrant provision

Play in the playground with librarian-puppet

The Puppet Playground provides also integration with librarian-puppet for a smarter management of Puppet code and the relevant modules. The intention is to provide a rich set of predefined toasters (or call them appliances or bundles of ready-to-cook recipes for a more or less complex setup), which can be quickly tested on different operating systems.

You can experiment with them with the included play command. It basically copies configurations from the selected toasters/ directory to manifests/init.pp and Puppetfile and runs librarian-puppet to automatically install the required modules in the modules/ directory.

To show the status of the playground

    ./play status

To show the available toasters for ./play install:

    ./play list

To install a specific toaster via librarian-puppet:

    ./play install garethr-riemann

To run the current playground (same as vagrant provision)

    ./play run

To cleanup the whole playground (Beware all the existing changes will be wiped off)

    ./play clean

To run puppi commands on all the active boxes (note: Puppi must included in the playground)

    ./play puppi check
    ./play puppi info

What's next?

Puppet Playground has just been released, and it's already useful. However, there is room for growth and improvement.

Everybody can help, with little effort, to make the Puppet Playground better:

  • If you have or know of good updated Vagrant base boxes for new OSes (they need Puppet installed and Vagrant ssh and shared folders working), you can add them to the default VagrantFile.
  • If you have toasters that use your modules for the setup of an appliance you can add them to the toasters directory (you need to provide a librarian-puppet's Puppetfile and a init.pp with the sample code and optionally a custom Vagrantfile).
  • If you have ideas or additions for better automation, smarter integrations or whatever might work here, suggest or push them.

Any relevant pull-request to https://github.com/example42/puppet-playground via GitHub is very welcomed, the Puppet Playground is more fun if there are more kids around :-)

Alessandro Franceschi

Learn more

Leave a comment