Script for adding multiple Vagrant boxes

I’ve been using Vagrant for a while now to test new configurations with simple virtual machines. Usually it’s just a single VM that I’m using but now I wanted to do some tests on more than one machine at the same time.

So I was looking for a way to easily create multiple identical virtual machines with Vagrant but couldn’t find a good solution so I made this small script to do it for me. If you know a better way, could you leave a comment and then we can both laugh at this script. I have also included a guide for controlling these new VMs with Fabric.

The script copies a packaged vagrant box as many times as you define and adds them to vagrant. Then adds the new virtual boxes to the Vagrantfile config. These new vagrant machines have hostonly static IP network setting but you can change it to bridged in the script if you want IPs from DHCP. The hostonly means that the machines can only be accessed from the host machine that’s running vagrant.

If you want to use multiple vagrant boxes without the script, here are the steps:
Create a single Vagrant box. Guide
Package it. Guide
Copy the package.box file. You need a copy for each virtual box. Guide ;)
Add the new box copies to vagrant. Guide
Add new config to Vagrantfile for each new box. Guide
Start the boxes with ‘vagrant up’

And here’s the guide for using my script:

Tested with:
Ubuntu 12.04
Vagrant 1.0.2

1. Install one vagrant machine first if you don’t have any. You can use the official Vagrant guide. Or this script. The script installs one Vagrant base machine and configures it so that we can use the actual script for adding more machines. So if you used the script you can skip to step 5. If you want to just trust me and skip everything you can just read the Summary in the end.

2. Install libnss-mdns to your lucid32 machine so that we can use .local hostnames. This is useful if you are using bridged network mode with vagrant boxes:
vagrant up
vagrant ssh
sudo apt-get update
sudo apt-get -y install libnss-mdns
exit

3. Change the machine’s network setting to hostonly with 10.10.10.10 IP:
cat Vagrantfile | sed s/'# config.vm.network :hostonly, \ "192.168.33.10"'/'config.vm.network :hostonly, "10.10.10.10"'/\
> tmpvag

mv tmpvag Vagrantfile

4. package your machine:
vagrant package

5. And here’s the script, copy and execute:

vagmulti.sh

#!/bin/bash

echo "Number of VMs to be created(1-99): "
read NUMBER
COUNT=1
echo "####################################"

until [ $COUNT -gt $NUMBER ]; do {
cp package.box vbox$COUNT.box
vagrant box add vbox$COUNT ./vbox$COUNT.box
rm vbox$COUNT.box
sed '$d' < Vagrantfile > tmpvag ; mv tmpvag Vagrantfile
cat >> Vagrantfile << EOF
    config.vm.define :vbox$COUNT do |kconfig_$COUNT|
    kconfig_$COUNT.vm.box = "vbox$COUNT"
    #kconfig_$COUNT.vm.network :bridged    # uncomment to use IPs from DHCP
    kconfig_$COUNT.vm.network :hostonly, "10.10.10.1$COUNT"
  end
end
EOF
echo "VM vbox$COUNT created"
let COUNT=COUNT+1
}
done
echo "Run 'vagrant up' to start all VMs"
echo "Run 'vagrant up vbox1' to start vbox1"

You can list the boxes with this command:
vagrant box list

6. Now the virtual boxes have been created, but they are not running yet. If you’re not sure how many virtual
boxes your machine can handle, start them one by one like this:
vagrant up base
vagrant up vbox1
vagrant up vbox2

If you are really sure, start them all with this:
vagrant up

If you’re using bridged network setting, Vagrant might ask you: “What interface should the network bridge to?”. Choose the same one that your host machine uses to get its IP from the DHCP.

All of these machines have the same hostname lucid32.
You can connect to them by IP address or by using lucid32.local, lucid32-1.local, lucid32-2.local, lucid32-3.local and so on as a hostname. The username and the password is “vagrant”.

The boxes are identical but if you need different kinds of boxes, you can just modify the Vagrantfile config and then reload the appropriate box:
vagrant reload vbox3

Fabric control

I use Fabric to control the virtual machines so I made a small script to list all those lucid32 machines in a file. The file can then be read and used as Fabric’s host variable.

hostlist.sh

#!/bin/bash

echo "Hostname: "
read NAME

echo "Domain: "
read DOMAIN

echo "Number of $NAME.$DOMAIN hosts: "
read NUMBER
COUNT=1

echo "$NAME.$DOMAIN" > $NAME.list
until [ $COUNT -gt $NUMBER ]; do {
    echo "$NAME-$COUNT.$DOMAIN" >> $NAME.list
    let COUNT=COUNT+1
}
done
echo "$NAME.list created"

Usage
chmod +x hostlist.sh
./hostlist.sh

Hostname:
lucid32

Domain:
local

Number of lucid32.local hosts:
5

lucid32.list created

This creates a file lucid32.list with the hostnames:

lucid32.local
lucid32-1.local
lucid32-2.local
lucid32-3.local
lucid32-4.local
lucid32-5.local

Alternative: iplist.sh
You can create a list of IP addresses with this one.

Now we still need to use the lucid32.list with Fabric. Let’s create a function for reading the list.

fabfile.py

from fabric.api import *

env.user="vagrant"
env.password="vagrant"
env.skip_bad_hosts=True
env.timeout=3

def hfile(file="lucid32.list"):
    env.hosts = open(file, 'r').readlines()

Now if we want to run a task called install_e3 on the lucid32 machines:
fab hfile install_e3

If you have more than one file with hosts, you can use this to define the file:
fab hfile:xubuntu.list install_e3
Or if you used iplist.sh:
fab hfile:10.10.10.10.list install_e3

The lucid32.list was just defined as the default file if no other filenames are given.

You can use this fabfile if you don’t have one already or this script to install fabric and fabfile.

There seems to be sometimes problems with .local hostnames (name lookup failed).
If this happens, you can try restarting the avahi-daemon on the vagrant machines
sudo service avahi-daemon restart
or you can use IP addresses instead of hostnames.

Summary

So total of three scripts that will get you to control multiple Vagrant virtual machines with Fabric.
vaginit.sh Installs and configures the first Vagrant box.
vagmulti.sh Let’s you create more virtual machines.
hostlist.sh Creates a list of the VM hostnames for Fabric. Use iplist.sh if you prefer IP addresses.

Additional script for installing and creating fabfile: fabi.sh

Usage:
wget https://raw.github.com/awaseroot/awaseroot/master/scripts/vagrant/vaginit.sh
wget https://raw.github.com/awaseroot/awaseroot/master/scripts/vagrant/vagmulti.sh
wget https://raw.github.com/awaseroot/awaseroot/master/scripts/vagrant/hostlist.sh
# Optional: #
#wget https://raw.github.com/awaseroot/awaseroot/master/scripts/vagrant/iplist.sh
#wget https://raw.github.com/awaseroot/awaseroot/master/scripts/vagrant/fabi.sh
#chmod +x iplist.sh fabi.sh
########
chmod +x vaginit.sh vagmulti.sh hostlist.sh
./vaginit.sh
vagrant@10.10.10.10’s password: vagrant
./vagmulti.sh
Number of VMs to be created(1-99):
5
vagrant up

./hostlist.sh
Hostname:
lucid32
Domain:
local
Number of lucid32.local hosts:
5

#./iplist.sh
#IP of the first host:
#10.10.10.10
#Number of hosts:
#5
#./fabi.sh

Use the hostfile with Fabric:

def hfile(file="lucid32.list"):
    env.hosts = open(file, 'r').readlines()

fab hfile task

Sources
http://vagrantup.com/
(The official Vagrant site)
http://vagrantup.com/docs/multivm.html
(Useful information about Multi-VM environments with Vagrant)

About these ads

One response to “Script for adding multiple Vagrant boxes

  1. Pingback: How to use Virtualization Tool Vagrant on Ubuntu-12.04 ?? | Thangamaniarun's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: