Vagrant: Create a multi-machine environment

Note: this is not a vagrant tutorial, its just a presentation of a Vagrantfile that could do your life easier!.

Note: this is not a vagrant tutorial, its just a presentation of a Vagrantfile that could do your life easier!.

Vagrant is a tool that allows you very easy to create development environments and small labs. So i have create this script that covers the following needs:

  • This script is somehow like a template, with minimum modifications in a config section you can add /remove as many VMs you want
  • You can easily modify the resources of each VM.
  • It uses the vagrant-hostmanager plugin, this plugin modifies the /etc/hosts file of your computer and makes the VMs accessible from your computer with their hostnames.
  • When you do vagrant destroy it reverts any changes to /etc/hosts
  • it copies your public key to the VMs for passwordless SSH

Vagrantfile with some inline comments# -*- mode: ruby -*-
# vi: set ft=ruby :
# Tested environment
# OS: ubuntu 20.04
# Vagrant: 2.2.6
# Hypervisor: virtualbox 6.1
# Box: centos/7
# Required plugin:
# vagrant-hostmanager (1.8.9, globalNETWORK = "192.168.50."
NETMASK = "255.255.255.0"
# VM machines configuration
# ip address of the vm is NETWORK plus the last part of the IP
HOSTS = {
  #VM_NAME      IP_ADDRESS    RAM(mb)  GUI    BOX
  "slave01" => [NETWORK+"10", 512,     false, 'centos/7'],
  "slave02" => [NETWORK+"11", 512,     false, 'centos/7'],
}
# A trick to read your SSH public key
# Then the public key is appended to /home/vagrant/.ssh/authorized_keys of the VM
ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
Vagrant.configure("2") do |config|
 # Those are options for the hostmanager plugin
 # hostmanager add records to /etc/hosts to enable
 # guests to guests and host to guests communication with hostnames
 # To enable the plugin
 config.hostmanager.enabled           = true
 # To enable add records to host /etc/hosts
 config.hostmanager.manage_host       = true
 # To enable add records to guest /etc/hosts
 config.hostmanager.manage_guest      = true
 # Not use private ip addresses for the hosts file, set to false
 config.hostmanager.ignore_private_ip = false
 config.hostmanager.include_offline   = true
 HOSTS.each do |(name, cfg)|
   ipaddr, ram, gui, box = cfg
   if ARGV[0] != 'destroy'
      config.vm.provision 'shell', inline: "echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys", privileged: false
   end
   config.vm.define name do |machine|
      machine.vm.box = box
      machine.vm.provider "virtualbox" do |vbox|
         vbox.gui    = gui
         vbox.memory = ram
         vbox.name   = name
      end
      machine.vm.hostname = name
      # Deleting entries from known_hosts on 'destroy'
      if ARGV[0] == 'destroy'
         puts("Deleting entries from known_hosts")
         system("ssh-keygen -f #{Dir.home}/.ssh/known_hosts -R '#{name}'")
         system("ssh-keygen -R #{ipaddr}")
      end
      machine.vm.network 'private_network', ip: ipaddr, netmask: NETMASK
   end
 end
end

How to use the script

Place the script in a proper directory$ mkdir -p ~/vagrant/test
$ cp Vagrantfile ~/vagrant/test

Install the vagrant-hostmanager plugin$ vagrant plugin install vagrant-hostmanager

Edit the Vagrantfile to match your needs$ vim ~/vagrant/test/Vagrantfile

Start vagrant$ cd ~/vagrant/test
$ vagrant up

If everything gone well the VMs will boot, and you will be capable to SSH your VMs from the host using their hostnames passwordless.