In this blog post, we will be discussing Vagrant, a powerful tool for managing virtual machines (VMs). With Vagrant, you can easily spin up multiple VMs with just a few commands, making it perfect for testing and development environments. We will demonstrate how to create a couple of VMs using VirtualBox as our provider.
To follow along with this tutorial, you should have both Vagrant and VirtualBox installed on your system. If you haven't installed them yet, you can find the installation instructions here:
Directory Structure
For this tutorial, we will be using the following directory structure:
.
├── Vagrantfile
└── install_common.sh
The Vagrantfile
is the main configuration file for Vagrant, and the install_common.sh
file contains any additional setup. We will be using this file to install common packages on both the master and slave VMs.
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
# Configurable variables
## Common configuration
boxVersion = "ubuntu/focal64"
## Master Configuration
masterName = "dmaster"
masterIp = "192.168.56.10"
masterCpus = 2
masterMemory = 2048
## Node Configuration
numberOfNodes = 2
nodeNamePrefix = "dnode"
nodeIpPrefix = "192.168.56.1"
nodeCpus = 1
nodeMemory = 1024
# Main Script
Vagrant.configure("2") do |config|
# master server
config.vm.define masterName do |dmaster|
dmaster.vm.box = boxVersion
dmaster.vm.hostname = masterName
dmaster.vm.box_url = boxVersion
dmaster.vm.network :private_network, ip: masterIp
dmaster.vm.provider :virtualbox do |v|
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--memory", masterMemory]
v.customize ["modifyvm", :id, "--name", masterName]
v.customize ["modifyvm", :id, "--cpus", masterCpus]
end
config.vm.provision "shell", inline: <<-SHELL
sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
service ssh restart
SHELL
dmaster.vm.provision "shell", path: "install_common.sh"
end
(1..numberOfNodes).each do |i|
nodeName = nodeNamePrefix + i.to_s
nodeIp = nodeIpPrefix + i.to_s
config.vm.define nodeName do |dnode|
dnode.vm.box = boxVersion
dnode.vm.hostname = nodeName
dnode.vm.network "private_network", ip: nodeIp
dnode.vm.provider "virtualbox" do |v|
v.name = nodeName
v.memory = nodeMemory
v.cpus = nodeCpus
end
config.vm.provision "shell", inline: <<-SHELL
sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
service ssh restart
SHELL
dnode.vm.provision "shell", path: "install_common.sh"
end
end
end
This Vagrantfile
will install and configure 1 Master VM and 2 Worker VMs.
Here's a breakdown of the Vagrantfile
:
- The file starts by defining configurable variables, which allow you to customize the VM configurations,
such as the
VM's base box
,CPU
,memory
, andIP address
. - The
Vagrant.configure("2") do |config|
block is where the main configuration takes place. - The master VM is defined with the name
dmaster
, and its settings are applied within theconfig.vm.define masterName do |dmaster|
block. - The worker VMs are created using a loop that iterates over the specified number of nodes (
numberOfNodes
). Each worker VM is assigned a unique name and IP address based on thenodeNamePrefix
andnodeIpPrefix
variables. - For each VM, the
box
version,hostname
, andnetwork
settings are configured. Additionally, the provider-specific settings, such asmemory
andCPU
allocation, are applied within thednode.vm.provider "virtualbox" do |v|
block. - Lastly, a shell provisioner is used to update the
SSH
configuration to enableChallengeResponseAuthentication
and restart theSSH
service. Theinstall_common.sh
script is also executed, which you can customize to include any additional setup or installation steps.
install_common.sh
#!/bin/bash
## install common
HOSTNAME=$(hostname)
IP=$(hostname -I | awk '{print $2}')
echo "START - install common - "$IP
echo "Add host name for ip"
host_exist=$(cat /etc/hosts | grep -i "$IP" | wc -l)
if [ "$host_exist" == "0" ];then
echo "$IP $HOSTNAME " >/etc/hosts
fi
echo "END - install common - " $IP
Creating the VMs
To create the VMs, follow these steps:
- Create a new directory for your project and place the
Vagrantfile
and theinstall_common.sh
files in it. - Open a terminal or command prompt and navigate to the directory containing the
Vagrantfile
. - Run the command
vagrant up
. Vagrant will download the required box (if not already cached) and create the master and worker VMs as specified in theVagrantfile
.
Accessing the VMs
Once the VMs are up and running, you can access them using the ssh
command followed by the VM ip, for example:
- To access the master VM:
ssh vagrant@192.168.56.10
(The default password isvagrant
) - To access the first worker VM:
ssh vagrant@192.168.56.11
(The default password is alsovagrant
) - You can also verify the status of your VMs by running the
vagrant status
command. - You can stop the VMs by running the
vagrant halt
command. - You can destroy the VMs by running the
vagrant destroy
command.
Good Job! 🍾
In this blog post, we have demonstrated how to create multiple VMs using Vagrant and VirtualBox. By using a simple Vagrantfile
,
we can quickly create and manage VMs for testing and development purposes. Vagrant provides a powerful, flexible,
and efficient way to manage your virtual environments.