Extending Vagrant Boxes
It’s a common case in Vagrant wanting to have base boxes that contain certain package or specific software to be able to create different type of clusters with little effort.
The most common case when using Vagrant is to specify a script that will download the software and prepare the box on startup, but this is quite inefficient, specially if we are downloading a lot of information from the internet that could be common for many of the instances.
Defining your own boxed extending from a base image
For the examples I will use CentOS (centos/7
) as a base image as it is one of the most common server OS.
Defining a box using Inline script
Using the inline script capabilities is the fastest way to define what our custom box will require:
Vagrantfile
:Vagrant.configure("2") do |config| config.vm.box = "centos/7" config.ssh.insert_key = false config.vm.provision "shell", inline: <<-SHELL yum update -y yum install -y git SHELL end
Defining a box Using external script
For the cases where we need to do more complex installation, it is cleaner to create a external script and point to it from the Vagrantfile
.
Vagrantfile
:
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.ssh.insert_key = false
config.vm.provision :shell, path: ".vagrant/scripts/init.sh"
end
An example of init script could be:
.vagrant/scripts/init.sh
:#!/usr/bin/env bash yum update -y yum install -y git
The location of the script can be anywhere in the directory where the VagrantFile
is, but I like to keep the init scripts under .vagrant
directory, so they are used the first time the Virtual machine is started, but never copied into it (Vagrant ignored the context of this directory by default).
Installing the extend box
I have noticed that the generated boxes only work correctly when the vguest plugin installed, so I advice to install it before running any of the scripts below. This can be done running vagrant plugin install vagrant-vbguest
.
To install the box we will create a vagrant virtual machine that will download and install all the specified software, turn it off and package it into a box to install it in the vagrant boxes repo.
the script below can do all this steps in one go and will clean the generated files after.
BOX_ID="<your box id>"
vagrant destroy -f
set -e
vagrant up # Start the box and run any defined scripts
vagrant package --output ${BOX_ID}.box # Store the virtual machine with all the software installed into a box file.
vagrant box add --force ${BOX_ID} ${BOX_ID}.box # Add the box to the vagrant repo using the given id.
vagrant destroy -f # Stop the vagrant instance
rm ${BOX_ID}.box # Remove the file
Once the the previous steps are completed, you can use your newly created box as base assigning the id (BOX_ID
value) to config.vm.box
:
Vagrant.configure("2") do |config|
config.vm.box = "<box id>"
...
end
In the next article I will show how to configure these boxes to create clusters.