Puppet and vagrant
So I’ve been playing with Puppet and Chef for server provisioning. The two technologies attempt to fill the same, or at least similar tasks: managing system configuration. With Vagrant, testing these two systems has become extremely easy. Vagrant supports both methods for server provisioning and the turnaround time for the tests is extremely short.
I have tried for quite a while to run chef on a system, to no avail. I’ve often found that an unexpected crash puts end to my testing, whereas the first times I tried puppet I achieved success. I also feel the declarative style with which the puppet modules are built really suits the problems that puppet solves.
This post is less of a comparison of Chef vs Puppet, perhaps the first in a series comparing the two, but for now we start with Puppet.
Simple configuration
Tools used:
- vagrant
- puppet
- librarian-puppet
I’m not going to go into details about the installation of the tools, apart from to say that vagrant is installed from the vagrant website and puppet/librarian-puppet are installed as gems.
A project can be completetly defined (for example for version control) in four files:
- Vagrantfile
- Puppetfile
- Gemfile
- manifests/default.pp (by convention)
The directory layout for the project, and what should be checked into version control is
.
├── Gemfile
├── Puppetfile
├── Vagrantfile
└── manifests
└── default.pp
The Gemfile
stores the ruby gem versions, the Puppetfile
sets the puppet modules, the Vagrantfile
configures the virtual machine and the manifests/default.pp
file defines the state of the virtual machine.
Gemfile
A simple portable gemfile stores the required gems (puppet and librarian-puppet) and gives the option to version them. An example gemfile is
source "https://rubygems.org"
gem 'librarian-puppet'
gem 'puppet'
Vagrantfile
This is where the vagrant virtual machine configuration is stored. The operating system and provisioning settings are stored here. A minimal example is given below, and sets up the box to use (precise64) and configures the puppet provisioning.
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "precise64"
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "manifests"
puppet.manifest_file = "default.pp"
puppet.module_path = "modules"
end
end
librarian-puppet
A major part of development is the DRY principle, and applies to package configuration also. librarian-puppet
allows pre-build and tested modules to install common packages. Puppetlabs maintain a repository of modules at puppet forge, or on github and these can be configured and managed through librarian-puppet. An example configuration is given below:
forge "https://forge.puppetlabs.com"
mod 'puppetlabs/stdlib'
mod 'puppetlabs/postgresql'
mod 'puppetlabs/apt'
where the mod
lines define the required modules with the author prefix, and the forge line defines the source. The syntax is remarkably similar to the Gemfile.
manifests/default.pp
This file describes the final configuration. I recommend following the official puppet tutorial, an example file which installs vim can be:
exec { "apt-get update":
path => "/usr/bin",
}
package { "vim":
require => Exec["apt-get update"],
ensure => present,
}
though this does not use the modules. These can be defined and configured by reopening the class declaration, e.g.
# Puppetfile
mod 'puppetlabs/postgresql'
# manifests/default.pp
exec { "apt-get update":
path => "/usr/bin",
}
package { "vim":
ensure => present,
require => Exec["apt-get update"],
}
class { "postgresql::client":
require => Exec["apt-get update"],
}
This configuration will install the vim
and postgresql::client
packages ensuring that apt-get update
has been run before.
Starting a project from scratch
These files can be initialised through three commands:
bundle init
,vagrant init
,librarian-puppet init
,
which are then configured to the users needs. Commands to run to create the full working system are
bundle install
bundle exec librarian-puppet install
vagrant up
Simple eh? More documentation for these files can be found: