In this series of blog posts, we will write a Puppet module that manages OpenLDAP client and OpenLDAP server. We will make this module compatible with both Debian 7 and RedHat 7. We will explain all the aspects of Puppet Agile development through the detailed examples of class, define, type, provider, function, and fact. Disclaimer: This blog posts are widely inspired by the wonderful tutorial to write puppet-lint plugins, so you may notice some similarities in structures or sentences.
- Ruby 1.9.3 (or above) and knowledge of the language
- Knowledge of the rspec testing framework
- Knowledge of the Beaker acceptance framework
- Knowledge of serverspec
First, get a skeleton project set up. The first thing you need to do is create a folder for your project. For convention’s sake, you should use
Every project needs a README file. It is common to use markdown to style its content.
If you are not familiar with the various licenses commonly used in Open Source projects, visit « Choose A License » to have a look at some options. When you find one you are happy with, drop it in a file called LICENSE in the root of your project.
You should add a file named
metadata.json in the root of your project in order to store some metadata needed to publish your module on the Puppet Forge.
A few interesting lines:
Line 8 – 9
For the moment, we do not have dependencies, but we will probably have at least puppetlabs-stdlib later.
Line 10 – 23
Declare the operating system supported by your module; this information will be automatically used by rspec-puppet-facts to loop over any supported operating system for tests.
Configure acceptance tests
We will use Beaker to launch acceptance tests. Beaker is the Puppetlabs’s acceptance testing tool used to test the behavior of a Puppet module on different operating systems. It can run tests on various hypervisors, including virutalbox (through Vagrant), Docker or OpenStack. You can use Beaker to test serverspec resources.
Bundler is a dependency manager tool for Ruby projects. It reads its configuration from the project’s Gemfile.
Tells Bundler to fetch dependencies from RubyGems over HTTPS.
Line 3 – 4
Our project depends on puppet and beaker-rspec. Now that our Gemfile is in place, let’s tell bundler to install everything needed to write our module.
Add node files
You need to add a node file for Beaker. Node files indicate the nodes that the tests will be run on. Create the folder where the nodesets will be stored:
Now, we’ll create two nodesets to run acceptance tests on Vagrant. One for Centos 7 64bits in spec/acceptance/nodesets/centos-7-x86_64-vagrant.yml:
Platform to use to setup Beaker
Hypervisor to use; here we’ll use Vagrant because it is probably the most robust one for now, but you could also try with another hypervisor such as Docker or OpenStack.
Vagrant box to use (from https://vagrantcloud.com)
Tells Beaker that we are using Puppet OpenSource (installation path differs from Puppet Enterprise) And one for Debian 7 64bits in spec/acceptance/nodesets/debian-7-x86_64-vagrant.yml:
Next, you need to create a spec/spec_helper_acceptance.rb file to configure Beaker:
Line 3 – 6
Install Puppet on every host in our nodeset. Beaker supports multiple hosts in a nodeset. This functionality will not be explained here.
Tells Beaker to scp our sourcedir into the spawned virtual machine’s /etc/puppet/modules.
Configure unit tests
We will use rspec-puppet to run unit tests.
puppetlabs_spec_helper gem provides some helpers to ease rspec-puppet configuration. Let’s add it to our Gemfile:
The .fixtures.yml file is a YAML file used by puppetlabs_spec_helper to setup an environment for your modules with all its dependencies in the
spec/fixtures directory. You have to, at least, add an entry that adds a symlink to your code base:
You need to require
puppetlabs_spec_helper/rake_tasks in your
Rakefile so that you can call the
spec rake task that will run the
spec_prep task for preparing your test environment using the .fixtures.yml file, then run the
spec_standalone task that actually launches the unit tests, and finally run the
spec_clean task to clean up your testing environment by deleting all the stuff in the spec/fixtures directory.
require 'puppetlabs_spec_helper/module_spec_helper' for now
Now that you have completed the setup of your environment, you are ready to start writing your module with TDD, as we will see next, in Part 1!