Creating a puppet test environment based on production server - Part 1

I decided to do few modules that will build an identical server configuration based on a production server of mine.

First I created a project folder where all the project files are created.

mkdir vhost
cd vhost
git init

I used Vagrant to create a virtual machine where my puppet modules will be deployed.

Creating the Vagrantfile for the environment

nano Vagrantfile

I wrote a Vagrantfile that creates one virtual machine where all the modules will be run: do |config|
    config.vm.provision :puppet do |puppet|
        puppet.module_path = "modules"
        puppet.manifest_file = "site.pp"

    config.vm.define :web1 do |apache_config| = "precise64"
        apache_config.vm.box_url = "" :hostonly, ""
        apache_config.vm.host_name = "web1.labra.local"

Creating Apache module with virtual hosts

I created a new module called apache which will install Apache and with a defined type vhost allow creating of virtualhosts for Apache.

First I created the default module directory structure:

mkdir -p modules/apache/manifests
mkdir -p modules/apache/templates

Then I created the main init.pp file:

nano modules/apache/manifests/init.pp

And wrote the following in it:

class apache {
        package {'apache2':
                ensure => installed,
                require => Exec['apt-update'],

        service {'apache2':
                ensure => running,
                require => Package['apache2'],
        exec { "apt-update":
                command => "/usr/bin/apt-get update"

The main manifest installs Apache and starts it if it is not running already. The exec-command is only needed for Vagrant because it does not update package lists automatically, more about the problem in here.

 Apache Virtualhosts with defined types

For the Apache Virtualhosts I used my modified version of the Puppetlabs-apache defined type vhost code.

I created the vhost.pp file for the virtualhost type:

nano modules/apache/manifests/vhost.pp

I modified the Puppetlabs code to be a bit simplified version for my configuration:

define apache::vhost(
        $docroot        = '/var/www-${name}',
        $template      = 'apache/vhost-default.conf.erb',
        $priority      = '25',
        $servername    = '',
        $serveraliases = '',
        $options       = "Indexes FollowSymLinks MultiViews",
        $vhost_name    = '*'
      ) {

      include apache

      # Below is a pre-2.6.5 idiom for having a parameter default to the title,
      # but you could also just declare $servername = "$title" in the parameters
      # list and change srvname to servername in the template.

      if $servername == '' {
        $srvname = $title
      } else {
        $srvname = $servername
      case $operatingsystem {
        'centos', 'redhat', 'fedora': { $vdir   = '/etc/httpd/conf.d'
                                        $logdir = '/var/log/httpd'}
        'ubuntu', 'debian':           { $vdir   = '/etc/apache2/sites-enabled'
                                        $logdir = '/var/log/apache2'}
        default:                      { $vdir   = '/etc/apache2/sites-enabled'
                                        $logdir = '/var/log/apache2'}
      file {
          content => template($template),
          owner   => 'root',
          group   => 'root',
          mode    => '755',
          require => Package['apache2'],
          notify  => Service['apache2'],


Creating the master site definition for Vagrant Puppet provision

First I created a manifests-directory to my project directory root where I created a site.pp file for Vagrant to run:

mkdir manifests
nano manifests/site.pp

I defined my one node in the file to install Apache and MySQL Server, create two users for the sites and finally create two virtualhosts with the names jonijunni.labra.local and synkkasiiseli.labra.local:

node 'web1.labra.local' {
        apache::vhost { 'jonijunni.labra.local':
                priority => '20',
                port => '80',
                docroot => '/home/jonijunni/public_html',
                require => User['jonijunni'],
        apache::vhost { 'synkkasiiseli.labra.local':
                priority => '20',
                port => '80',
                docroot => '/home/synkkasiiseli/public_html',
                require => User['synkkasiiseli'],
        user::user { 'jonijunni':
                username => 'jonijunni',
        user::user { 'synkkasiiseli':
                username => 'synkkasiiseli',

        include mysql

After that I deployed the virtual machine:

vagrant up


Finally I tested with my browser that the virtual hosts work:


For the domain name to work you need to have the name configured on the DNS-server on your network or in your hosts-file.

Commiting to Git repository

git add .
git commit
git pull && git push

Git Log

<pre class="wp-code-highlight prettyprint">commit 2746c1444cd568594829fa59c3ed958e6994d5a2
Author: Joni Junni <joni@xenon.(none)>
Date:   Mon Dec 9 10:01:34 2013 +0200

    Fixed apt-get update problem

commit 5c51013b74d0a8505b1d4befbb464ff3cc2105ad
Author: Joni Junni <joni@xenon.(none)>
Date:   Mon Dec 9 09:16:15 2013 +0200

    Fixed thingies

commit e948a7c53e69acec097e0396a59259dff0c5d34f
Author: Joni Junni <joni@xenon.(none)>
Date:   Sat Dec 7 12:57:35 2013 +0200

    Working web1 server with name resolving

commit a5eed82397955ecf7bccda1eeca1c8be7e468a5e
Author: Joni Junni <joni@xenon.(none)>
Date:   Sat Dec 7 12:23:03 2013 +0200

    Committing a new Vagrant project

Moving the repo to master server

I moved my project to a remote server for easier deployment.

Things to run on the remote server

mkdir vhost.git
cd vhost.git
git init --bare --shared

Things to do on the local repository

git remote add origin ssh://joni@xenon.local/home/joni/vhost.git
git push origin master
git branch --set-upstream master origin/master
git pull && git push


Cloning the repo to other machines

I cloned the repo to my development machine:

git clone ssh://joni@