Personally, I consider the script parameter in a Vagrantfile to be a feature that is not abused enough. It’s got a lot of potential - every script can have a parameter (or several). Modifying your Vagrant use to include this gives you a more flexible and reliable way of quickly deploying some test nodes.

That automation thing

While juggling around with Vagrant and provisioning boxes for the local test environment - which certainly is a lot of fun - I found myself deploying the same scripts on new hosts all the time. Even worse: when being lazy I just quickly installed the necessary tools manually.

When I repeat a certain task often enough, it crosses a border where it gets annoying. Annoying enough to be dealt with (that border is quite low actually). And I’d like to spend that time rather doing something else.

The idea is that a few small scripts could customize and generalize the installation of components on vagrant nodes very quickly - in the same way every time. Vagrant provides support for this through the script parameter in the Vagrantfile. By running scripts like this on a newly provisioned host, we can do pretty much anything we want with only a basic knowledge of bash.

These scripst are just quickly whipped together to deal with the repeating steps involved in repeatedly creating hosts with similar configurations. It is way below the level of complexity or capability of what you get with larger Configuration Management tools like Ansible, Chef og Puppet. At a certain level of complexity and with certain requirements, it might make more sense to integrate these tools instead of using custom scripts. But the simplicity of this solution might make it easier for beginners to reach at least some level of automation without diving into the deep waters of the full-blown configuration tools.

All of the code is available at Github, with examples.

The scripts

In the Vagrantfile, the following lines should look familiar:

client.vm.provision :shell,
  path: "",
  :args => [ "arg1", "arg2" ]

They basically pass a script including parameters to Vagrant and run the script on the host.

And this can be abused.

The structure

For this example the local Vagrant installation is combined with a VirtualBox. The basic principles are easy to understand and can be used in other setups.
The core of the setup is the file It handles all parameters and includes all the necessary files. (You’ll find this file and all of the other files included in the in the git repo mentioned in the beginning and at the end of the article). The script parses parameters and controls the order in which optional updates, hostfiles and other installations take place. It is also responsible for including the
Then there’s Santa’s little helper: It provides some basic id-ing of the distro and allows other scripts to use the right distro-specific commands. If you need to support another distro, add specifics in this file.
The, does what you’d guess from the name - it updates the installed packages on the system.
host specific installation files can run any kind of custom command on the host-level. They need to be named following the pattern bs.<fqdn>.sh.
The file handles the tags structure. These are basically directories with init-files. These init-files install a component on a host, they are not System V init-files. I usually use this like you would use Puppet Modules or Chef Cookbooks and either install and configure a single component or multiple (E.g. syslog, nfs-server, dhcp, etc.). By just including the tags as parameters, we include these automatically in the bootstrap process.

The name of the directory must be identical to the tag to use, ie. the tag webserver will trigger the file ./webserver/ In the example code you’ll find a setup for a (very basic) webserver installation. Also in the example: the directory tools and the required, which installs some generic basic tools.

./hosts/  # Hostfile for host
./tools/               # The Main process
./tools/        # Update script
./tools/          # Santa's helper
./tools/               # Tools-init script (install-tag)
./webserver/           # webserver-init script (install-tag) pulling it all together
The initial script called from Vagrantfileis the script. It starts by parsing parameters and gathering general information and then sets some environment variables.
  • If the hostname parameter has been set as well, the specific host-file is included and included commands are executed.

  • Then the rest of the installation tags are run, installing specific tools or more general applications.

An example

Depending on the parameters given in the Vagrantfile, the hosts will be setup differently using the method described above.

Node 1

The following Vagrant configuration will

  • Upgrade all packages on the host
  • do nothing else (because the example setup does not provide a bootstrap file)
host.vm.provision :shell,
  path: "bootstrap/tools/", 
  :args => [

Node 2

The following Vagrant configuration will

  • Upgrade all packages on the host.
  • Install a webserver.
  • Install custom tools
  • Run the commands in
host.vm.provision :shell,
  path: "bootstrap/tools/", 
  :args => [
    "-i webserver",
    "-i tools"

Future improvements

As always, there’s still some space for improvements:

  • Support more distributions, and make the scripts as distro agnostic as possible.

  • The code structure could probably require some restructuring.

The code is available at Github, and I would love it if you play around with it and send me pull-requests if you improve or extend ‘vagrant-lazy’.