My courses

Create Puppet module test case less than 5 minutes

In this post, I’ll tell you how to create Puppet module test cases. If you are newbie with Puppet, I recommend you begin by my another post Hello Puppet!.

My using operating system is Xubuntu 14.04 LTS.

Hello Git!

As every project begin in Hello world, by the same way our project begin in Hello Git!

Create directory structure:

$ mkdir -p puppet/modules/git/manifests
$ cd puppet

Create init.pp in manifests:

$ nano modules/git/manifests/init.pp

And write bottom lines in file:

class git {

  package { 'git':
    ensure => 'installed',


Run our git module:

$ puppet apply --modulepath modules/ -e 'class {"git":}'

And now git should be installed to our system.

Create test case

Is time to go on and let make our first test case. In web, I have seen many different variations to make this part of post. But I like to make things easiest way as possible, so I’ll show you how to make this part as simplest I know so far.

Goto git module root:

$ cd modules/git

Write necessary gems in Gemfile.

$ nano Gemfile

source ''
puppetversion = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : ['>= 2.7']
gem 'puppet', puppetversion
gem 'puppetlabs_spec_helper', '>= 0.1.0'
gem 'rspec', '>=3.1.0'
gem 'rspec-puppet'

And bundle install gems:

$ bundle install

Run command rspec-puppet-init, and we got full nicely generated spec directory structure:

$ rspec-puppet-init

 + spec/
 + spec/classes/
 + spec/defines/
 + spec/functions/
 + spec/hosts/
 + spec/fixtures/
 + spec/fixtures/manifests/
 + spec/fixtures/modules/
 + spec/fixtures/modules/git/
 + spec/fixtures/manifests/site.pp
 + spec/fixtures/modules/git/manifests
 + spec/spec_helper.rb
 + Rakefile

Rspec-puppet for some reason miss require puppetlabs_spec_helper. We add it into bottom of file:

$ echo "require 'puppetlabs_spec_helper/rake_tasks'" >> Rakefile

Write some test case. That is the way, how we verify and be sure that our git class contain package git.

$ nano spec/classes/git_spec.rb

require 'spec_helper'

describe 'git', :type => 'class' do
  context 'install git' do
    it { should contain_package('git') }

And now we’re able to run our test case. Because we are using Gemfile, is very important to run rake spec with bundle! If you’re not using bundle, you’re not even use Gemfile, so you’re not using your specified gems versions! It isn’t good practice, so use bundle:

$ bundle exec rake spec

/home/niko/.rvm/rubies/ruby-2.1.2/bin/ruby -I/home/niko/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.1.7/lib:/home/niko/.rvm/gems/ruby-2.1.2/gems/rspec-support-3.1.2/lib/home/niko/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration\}/\*\*/\*_spec.rb --color

Finished in 1.06 seconds (files took 0.78309 seconds to load)
1 example, 0 failures


Puppet parameterized class and Varnish reverse proxy

I am writing this post as part of course Linuxin keskitetty hallinta held by Tero Karvinen. In this article I will install Varnish reverse proxy and change its port by Puppet parametrized class. Double weeks ago I did article for how you install Apache with Puppet:

Create new module

Remember first start by hello world!

$ mkdir -p modules/varnishd/manifests/
$ nano modules/varnishd/manifests/init.pp

Code in init.pp:

class varnishd ($varnish_port = 80, $backend_port = 8080) {

  package {"varnish":
    ensure => "installed",

  service {"varnish":
    ensure => "running",
    enable => "true",
    require => Package["varnish"],


Run module:

$ puppet apply --modulepath modules/ -e 'class {"varnishd":}'

Create templates

First copy and modify varnish default config-file:

$ mkdir modules/varnishd/templates/
$ cp /etc/default/varnish modules/varnishd/templates/varnish.erb
$ nano modules/varnishd/templates/varnish.erb

Change port 6081 to variable @varnish_port:

DAEMON_OPTS="-a :<%= @varnish_port %> \

And next copy and modify varnish backend service config-file:

$ cp /etc/varnish/default.vcl modules/varnishd/templates/default.vcl.erb
$ nano modules/varnishd/templates/default.vcl.erb

Change backend port to variable @backend_port:

.port = "<%= @backend_port %>";

And last add two file method in init.pp

$ nano modules/varnishd/manifests/init.pp

And code in init.pp:

class varnishd ($varnish_port = 80, $backend_port = 8080) {
  package {"varnish":
    ensure => "installed",

  service {"varnish":
    ensure => "running",
    enable => "true",
    require => Package["varnish"],

  file { "/etc/default/varnish":
    content => template("varnishd/varnish.erb"),

  file { "/etc/varnish/default.vcl":
    content => template("varnishd/default.vcl.erb"),


Finally run command:

$ puppet apply --modulepath modules/ -e 'class {"varnishd":}'


$ curl -I localhost


HTTP/1.1 200 OK
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Thu, 21 Nov 2013 19:08:06 GMT
ETag: "c40836-d-4ebb49e1a8e3c"
Vary: Accept-Encoding
Content-Type: text/html
Transfer-Encoding: chunked
Date: Thu, 21 Nov 2013 19:29:59 GMT
X-Varnish: 1215889787
Age: 0
Via: 1.1 varnish
Connection: keep-alive

PuppetMaster and slaves on Ubuntu 12.04

I am writing this post as part of course Linuxin keskitetty hallinta held by Tero Karvinen. In this post I will be install PuppetMaster and I share my puppet configures to my slaves computers (virtual machines). This is very important part of centralized management because after that you will be able to manage your managed computers software in one place.

In this instructions I use multiple virtual machines by vagrant. If you want to use vagrant too, I have getting started post here:

Preinstall PuppetMaster I was getting up two virtual machines master and slave with same hostnames.

In Ubuntu 12.04 is not default installed avahi-daemon, so .local (mDNS) domains are not available. We would like to use .local domains with puppet, so we install avahi-daemon:

master$ sudo apt-get -y install avahi-daemon

I ping master computer by slave to verify that everything working as well:

slave$ ping master.local

Install PuppetMaster

master$ sudo apt-get -y install puppetmaster

Configure PuppetMaster

In some cases is better first delete puppet ssl certificates. Puppet genereta it to back when we start PuppetMaster again.

master$ sudo service puppetmaster stop
master$ sudo rm -r /var/lib/puppet/ssl

Modify Puppet config-file:

master$ sudoedit /etc/puppet/puppet.conf

Add master’s host under [master] -tag

dns_alt_names = puppet, master.local

Start PuppetMaster:

master$ sudo service puppetmaster start

Connecting slaves

Install puppet:

slave$ sudo apt-get -y install puppet

And modify config-file:

slave$ sudoedit /etc/puppet/puppet.conf

Add master DNS name under [agent] -tag:

server = master.local

Modify puppet to start automatically:

slave$ sudoedit /etc/default/puppet

Change start to yes:


Start puppet:

slave$ sudo service puppet restart

Accept Slave certificate

master$ sudo puppet cert --list

master$ sudo puppet cert --sign

Create new Puppet module

master$ cd /etc/puppet

master$ sudo mkdir -p modules/hello/manifests/

master$ sudoedit modules/hello/manifests/init.pp
class hello {
  file { '/tmp/hello':
    content => "Hello PuppetMaster!\n"

Create site manifest

master$ cd /etc/puppet
master$ sudoedit manifests/site.pp

Add next code line in site.pp:



slave$ sudo service puppet restart
slave$ less /tmp/hello

If hello file is no there immediately, wait some time and try again.


Puppet package-file-service example

I am writing this post as part of course Linuxin keskitetty hallinta held by Tero Karvinen. In this post I will create new package-file-service module and install apache2 by puppet.

If you need to help for installing puppet I recommend you beginning training puppet here:

Otherwise, let’s begin to install Apache2 by puppet!

Create new module

First create new module and init.pp file inside manifests:

$ mkdir -p modules/apache2/manifests/
$ nano modules/apache2/manifests/init.pp

And the code in init.pp:

class apache2 {
  package {"apache2":
    ensure => "installed",

  service {"apache2":
    ensure => "running",
    enable => "true",
    require => Package["apache2"],

Apply our puppet module by command:

$ puppet apply --modulepath modules/ -e 'class {"apache2":}'

Test module

We can test that Apache2 is running by command:

$ sudo service apache2 status

Apache2 is running


Puppet templates and facter facts hello world

I am writing this post as part of course Linuxin keskitetty hallinta held by Tero Karvinen. In this post I will write hello world module which use puppet templates and facter facts (ex. my hardware details).

See your computer details

When we run facter command, we will see our computer details. Read more:

$ facter -p

Create new module

Create new view for hardware_details module:

$ mkdir -p modules/hardware_details/templates/
$ nano modules/hardware_details/templates/details.erb

The code in details.erb:

Hardware model: <%= @hardwaremodel %>
Kernel version: <%= @kernelmajversion %>
Puppet version: <%= @puppetversion %>
Ruby version: <%= @rubyversion %>

Create new directory:

$ mkdir modules/hardware_details/manifests

Do next class in file modules/hardware_details/manifests/init.pp:

class hardware_details {
  file { '/tmp/hardwareDetail':
    content => template('hardware_details/details.erb'),

Run puppet module:

$ puppet apply --modulepath modules/ -e 'class {"hardware_details":}'

Test module

Last we verify that module works right:

$ less /tmp/hardwareDetails

My result:
Hardware model: x86_64
Kernel version: 3.2
Puppet version: 2.7.11
Ruby version: 1.8.7

© 2017 Niko Kiuru

Theme by Anders NorenUp ↑