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
 │   ├── deploy_puppetmaster.sh
 │   └── run_puppet.sh
 ├── README
 └── 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

Vagrant::Config.run do |config|
  config.vm.define :client do |client_config|
    client_config.vm.box = "base"
    client_config.vm.host_name = "client"
    client_config.vm.provision :shell do |shell|
      shell.path = "scripts/run_puppet.sh"
    end
  end
end

Run Puppet

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

#!/bin/bash
#
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.

#!/bin/bash
#
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: https://projects.vstone.eu/projects/puppet-showcase-puppetmaster.

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 ?

    • 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.

      • 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.

        • 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.

  2. 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

Your email address will not be published. Required fields are marked *