How to setup a dev environment using Vagrant & Puppet (Part II)

This is a continuation of my previous post on how to get up and running with Vagrant.

Now let’s get more specific and see how we can install specific modules.


To install PostgreSQL I’ve chosen to use this module on GitHub. Let’s go ahead and add that as a submodule. Run this command from the git root folder:

git submodule add puppet/modules/postgresql

Also keep in mind, the destination directory should have the same name as the main module’s class. So in this case, postgresql.

You can now add this module into your default.pp in puppet/manifests folder to start using it:

class { 'postgresql': }

That’s the most basic way to get started. Although to make things easier, we should probably also add any databases or users that we will need. And if you plan to access PostgreSQL from your host machine, you will also need to open up the port and allow incoming traffic from the host.

So taking those things into consideration, here’s what it would end up looking like:

class install_postgres {
  class { 'postgresql': }

  class { 'postgresql::server':
    listen => ['*', ],
    port   => 5432,
    acl   => ['host all all md5', ],  

  pg_database { ['some-project_database']:
    ensure   => present,
    encoding => 'UTF8',
    require  => Class['postgresql::server']

  pg_user { 'some-project-user':
    ensure  => present,
    require => Class['postgresql::server'],
    superuser => true,
    password => 'some-password'

  pg_user { 'vagrant':
    ensure    => present,
    superuser => true,
    require   => Class['postgresql::server']

  package { 'libpq-dev':
    ensure => installed

  package { 'postgresql-contrib':
    ensure  => installed,
    require => Class['postgresql::server'],
class { 'install_postgres': }

Finally in your Vagrantfile, make sure you are forwarding that port to whichever port you want on your host machine: :forwarded_port, guest: 5432, host: 5433


Now let’s take a look at how to go about installing Ruby. Instead of a package, we’ll just do this manually. First let’s defined a variable called $as_vagrant. It’s a reusable command which will let us basically run other commands as the vagrant user:

$as_vagrant = 'sudo -u vagrant -H bash -l -c'

We also need to make sure, curl is installed:

package { 'curl':
  ensure => installed

Now we can install RVM (note the dependency on the curl package):

exec { 'gpg_key':
  command => "${as_vagrant} 'gpg --keyserver hkp:// --recv-keys D39DC0E3'"

exec { 'install_rvm':
  command => "${as_vagrant} 'curl -L | bash -s stable'",
  creates => "${home}/.rvm/bin/rvm",
  require => [Package['curl'], Exec['gpg_key']]

Next up, install Ruby 2.0.0 (note the dependency on our previous install_rvm command):

exec { 'install_ruby':
  # We run the rvm executable directly because the shell function assumes an
  # interactive environment, in particular to display messages or ask questions.
  # The rvm executable is more suitable for automated installs.
  # Thanks to @mpapis for this tip.
  command => "${as_vagrant} '${home}/.rvm/bin/rvm install 2.0.0 --latest-binary --autolibs=enabled && rvm --fuzzy alias create default 2.0.0'",
  creates => "${home}/.rvm/bin/ruby",
  require => Exec['install_rvm']

Finally, install Bundler:

exec { "${as_vagrant} 'gem install bundler --no-rdoc --no-ri'":
  creates => "${home}/.rvm/bin/bundle",
  require => Exec['install_ruby']


For python I’ve chosen to use this module which makes it very easy to install.

Let’s add that as a submodule:

git submodule add puppet/modules/python

Now all you have to do is add this declaration:

class { 'python':
  version => 'system',
  virtualenv => true,
  pip => true,
  dev => true

You can checkout more params/arguments on their GitHub page.

If you’d like to learn more about creating and consuming modules, I would also recommend checking out Erika Heidi’s site for in-depth blog posts and talks.


Finally you are now ready to fire up your new Vagrant machine. Just run the following commands:

$ vagrant up
$ vagrant provision
$ vagrant ssh

You can now just go to the /vagrant folder where you should see the project folder that you just cloned. This folder is shared with your host so you can open your favorite editor on the host and start hacking away.


New version of Vagrant also includes the ability to Share, Distribute and Discover your Vagrant boxes. I have been sharing my Vagrant machine using ngrok, a utility that I mentioned in my previous post about useful web development tools. With the release of vagrant share, you could skip that and just do:

vagrant share --ssh

That will create a random shareable web URL such as which would point to your Vagrant instance.

This is very handy for sharing results with co-workers or remote debugging. On the flip side, you can also SSH into other Vagrant machines :

vagrant connect --ssh hulking-chameleon-3934

More details on how this works on their site.

That’s it, I think I’ve covered the basics. Let me know if you’d like to me cover anything else.

If you have any questions or comments, please post them below. If you liked this post, you can share it with your followers or follow me on Twitter!