Vagrant: Using the shell provider for running puppet.

The case for…

Why would you use the shell provider instead of the native puppet support?

Sometimes you want to tweak your base-box before running puppet, in that case, using a shell script might be a good idea. I started using the shell provider for deploying a puppetmaster. This way, I can initially bootstrap the puppetmaster using puppet apply and then have further configuration done by letting further configuration be done by just running puppet agent like I would in an actual environment.

The second advantage is that I sync my complete puppet tree to /etc/puppet vagrant box, making the differences with an actual deploy even smaller. If you need custom configuration files, you can use the proper file paths while developing and/or put them in your puppet folder.

The setup

This is how my folder structure looks:

 ├── graphs
 ├── puppet
 │   ├── hieradata
 │   ├── manifests
 │   ├── modules
 │   └── hiera.yaml
 ├── scripts
 │   ├──
 │   └──
 └── Vagrantfile

As you can see, stuff is nicely separated. Note that this also allows me to put a hiera.yaml file in place for use with hiera. When using the vagrant puppet provisioning, the hiera.yaml file must be present in the base-box. It also allows me to use git submodules for each part (e.g. the puppet directory which is a collection of more submodules).

Vagrantfile do |config|
  config.vm.define :client do |client_config| = "base"
    client_config.vm.host_name = "client"
    client_config.vm.provision :shell do |shell|
      shell.path = "scripts/"

Run Puppet

For running a puppet agent, I use the following script:

set -x

## We need rsync on the machine
[ -f /usr/bin/rsync ] || yum install -y rsync
# As a (faster) alternative, download the rpm locally and use:
# rpm -i /vagrant/rsync-3.0.6-5.el6_0.1.x86_64.rpm

## We need hiera - should be replaced by a rpm someday.
[ -f /usr/bin/hiera ] || gem install -r --no-rdoc --no-ri hiera hiera-puppet

## We also need the puppet folder
[ -d /etc/puppet ] || mkdir /etc/puppet

## Sync the puppet tree from the vagrant folder to the machine.
rsync -alrcWt --del --progress \
  --exclude=.git --exclude=.svn \
  /vagrant/puppet/* /etc/puppet/

puppet apply --debug --verbose \
  --graph --graphdir /vagrant/graphs \
  --modulepath /etc/puppet/modules/ /etc/puppet/manifests/site.pp

Deploy a Puppetmaster

For deploying / testing a puppet server, I use a slightly different script.

This will first bootstrap the puppet master using the same puppet apply method we use for testing a ‘client’ – but this will only perform minimal configuration. Once we have a puppetmaster running, we run a puppet agent on the machine that will configure the server against itself.

set -x

[ -f /usr/bin/rsync ] || yum install -y rsync
[ -f /usr/bin/hiera ] || gem install -r --no-rdoc --no-ri hiera hiera-puppet
[ -d /etc/puppet ] || mkdir /etc/puppet

## Sync the puppet tree from the vagrant folder to the puppet folder on the machine.
rsync -alrcWt --del --progress \
  --exclude=.git --exclude=.svn \
  /vagrant/puppet/* /etc/puppet/

## Execute the bootstrap
puppet apply --debug --verbose --trace \
  --graph --graphdir /vagrant/graphs \
  --modulepath /etc/puppet/modules \
  -e "import '/etc/puppet/manifests/classes/required-repos.pp' \
      import '/etc/puppet/manifests/classes/puppetmaster.pp' \
      include puppetmaster::bootstrap"

## Continue configuration using the set up puppetmaster
puppet agent --test --debug --verbose

I will not go into detail on what the puppetmaster manifest contain (for now) since I am still working on a demo setup. You can take a quick peek to the work that is done on this subject here:

6 comments on “Vagrant: Using the shell provider for running puppet.

  1. Interesting, but why use rsync and the bash fu around /etc/puppet ?

    For a puppet bootstrap on a client, at least it could be done with

    puppet apply –debug –verbose \
    –graph –graphdir /vagrant/graphs \
    –modulepath /vagrant/puppet/modules/ /vagrant/puppet/manifests/site.pp

    Then the first run hopefully poulate /etc/puppet/puppet.conf + /etc/default/puppet matching data from hiera, etc…

    No ?

  2. For a client this would be true, but not for the puppetmaster. After the bootstrap, the puppetmaster will use /etc/puppet and thus would fail unless you setup your puppet.conf to find manifests and modules in /vagrant/puppet/*.
    I am strongly against modifying the puppet.conf for a vagrant run. I like have configuration and/or paths as close as possible to the real life situation, even while developing. You would also need to change the hiera configuration to find the yaml files in /vagrant/puppet/hieradata.

    As for the bash fu around /etc/puppet, I agree this could probably be omitted because we know that puppet is installed. This could easily be adjusted to do a yum install puppet when the /etc/puppet folder does not exist. This way, one vanilla box could be used for doing both chef and puppet and whatever other system you want to use.

  3. Ack, fully bootstrapped puppetmaster needs the code in /etc/puppet/{manifests,modules}

    But at this point it is puppet code deployment, I’ll differentiate the operations :

    – bootstrap the puppet master
    – deploy puppet code
    – reload apache (I saw you’re using passenger)

    Rinse and repeat the last two, so altering your deployment process does’nt interfere with your bootstrap in the future.

  4. Thats a valid point I’ll have to look into. I only used it to test the bootstrapping part so I haven’t run into that wall yet.

  5. Very interesting stuff, especially for someone like me who is still a newcomer in Puppetland. I have been reading up on hiera integration and have been wondering about how to bootstrap adequately. Your article points in that direction, so thanks.

Leave a Reply