home rss

Puppet Infrastructure with r10k

25 Nov 2013


This tutorial shows how to use r10k to help manage dynamic Puppet environments. The Puppet Infrastructure tutorial can easily be supplemented by this tutorial. Just swap out the "Setting Up Version Control" section for this tutorial.

Dynamic Environments

Puppet has the ability to support different Environments. An environment is kind of like a Puppet virtual Host – it's a completely different Puppet configuration set hosted under a single Puppet Master.

One cool trick that came out a few years ago was to map git branches to Puppet environments. This practice became known as as Dynamic Environments. The big benefit that Dynamic Environments introduced was the ability to create new and cheap Puppet environments just as you would with Git branches.

A historical look at Dynamic Environments can be found here.

I've known of Dynamic Environments for over a year but never bothered with them. The main reason is that I'm usually the only person who maintains the various Puppet servers at $work, so I'm able to easily test out new changes without affecting anyone else.

However, this situation has recently changed. More people are beginning to work on the Puppet servers. In addition, some of the testing environments have slowly graduated to a sort of production environment where people quickly notice when something is broke. Finally, some of the Puppet servers that were deployed for specific projects might be able to be combined under a single Puppet Master.

A git-branch-per-environment scenario can assist with resolving these issues.

Configuring Puppet for Environments

Puppet's doc page does a great job at explaining Environments and how to configure them. This tutorial will assume the following configuration in /etc/puppet/puppet.conf:

modulepath = $confdir/environments/$environment/modules:$confdir/environments/$environment/
manifest = $confdir/environments/$environment/site/manifests/site.pp

modulepath is placed in main so puppet apply can take advantage of the different environments. This helps when Puppet is run in solo mode.

There are two paths given for modulepath:


r10k is a tool to help manage dynamic environments. It can handle creating new environments from git branches and deploying a set of modules to that environment.

This article should not be considered a de-facto guide for r10k. Please make sure to read the README file located at r10k's github site.

Installing r10k

Installation is simple:

$ sudo gem install r10k

Setting Up the Repository

Since git is the heart of Dynamic Environments, a git repository is needed. The repository's name can be anything you'd like. The location of the repository should be outside of /etc/puppet. This is because r10k will be cloning the repository into /etc/puppet itself.

$ cd ~/dev
$ git init r10k-site
$ cd r10k-site

Inside the repository, start working on a branch called production. I like to think of the "production" environment as being synonymous to the "master" branch in git: it's where you eventually want your production, stable configuration to reside.

If a Puppet node is not configured with an explicit environment, then an environment of "production" is assumed.

$ git checkout -b production


The r10k documentation explains that r10k will deploy modules specified in a Puppetfile if a Puppetfile is at the root of the branch:

$ touch Puppetfile

Site-local Module

To configure your site local module, which will contain compositional manifests and roles, do the following:

$ mkdir -p site/manifests/roles
$ touch site/manifests/roles/base.pp
$ touch site/manifests/packages.pp


That should be enough to get started. Save the changes and push them to a remote git repository:

$ echo modules > .gitignore
$ git add .
$ git commit -m "Initial commit"
$ git remote add origin https://github.com/user/r10k-site
$ git push -u origin production

Do not use a public Github repository if your Puppet configuration will contain sensitive information. {.alert .alert-error}

Make sure you add modules to your .gitignore file or your repository will contain the full set of modules that you'll be using in production. While there's really nothing wrong with this per se, it defeats the purpose of r10k and a Puppetfile.

Configuring r10k

Now configure r10k with a small yaml file located at /etc/r10k.yaml:

:cachedir: /var/cache/r10k
    remote: https://github.com/user/r10k-site
    basedir: /etc/puppet/environments

Run r10k

And finally, run:

$ sudo r10k deploy environment -p

If everything worked out, /etc/puppet/environments/production should exist. Additionally, /etc/puppet/environments/production/modules should contain all modules you placed in the Puppetfile.


/etc/puppet/environments/production is a git repository. You can make any changes in this environment and then commit them like normal:

$ git add .
$ git commit -m "Modified blah"
$ git push -u origin production


If you need to create a new environment, you can easily clone the Production environment:

$ git checkout -b havana
$ git push -u origin havana
$ sudo r10k deploy environment havana -p

And /etc/puppet/environments/havana should now exist. Just tag a few nodes with an environment value of havana and they're ready to run off of the new configuration.


This concludes a brief tutorial on setting up and using r10k.

This tutorial can be a supplement to the Puppet Infrastructure tutorial. If used this way, use this tutorial for the "Setting Up Version Control" section. When finished with this tutorial, continue on with the "Puppet Infrastructure" tutorial, but replace any occurrence of /etc/puppet/modules with /etc/puppet/environments/production/modules.


comments powered by Disqus