This post was originally published on this site

In case you want to prepare multiple sets of machines quickly using Vagrant, ready for different setups, this might be something for you:

## -*- mode: ruby -*-
## vi: set ft=ruby :

require 'ipaddr'

###############################
# CUSTOM CONFIGURATION START
###############################

# lab_name is the name of the lab where all the files will be organized.
lab_name = "lab_bigdata"

# here is where you download your software, so it will be available to the VMs.
sw_path  = "C:UsersludovDownloadsSoftware"

# cluster(s) definition
clusters = [
  {
  :prefix  => "hadoop", 				# prefix: VMs will be named prefix01, prefix02, etc
  :domain  => "ludovicocaldara.net",	# domain name
  :box     => "ludodba/ol7.3-base",		# base box, either "ludodba/ol7.3-base" or "ludodba/ubu1604"
  :nodes   => 3,						# number of nodes for this cluster
  :cpu     => 1,
  :mem     => 2048,
  :publan  => IPAddr.new("192.168.56.0/24"), 	# public lan for the cluster
  :publan_start => 121							# starting IP, each VM will increment it by one
  },
  {
  :prefix  => "kafka",							# eventually, continue with another cluster!
  :domain  => "ludovicocaldara.net",
  :box     => "ludodba/ol7.3-base",
  :nodes   => 1,
  :cpu     => 1,
  :mem     => 2048,
  :publan  => IPAddr.new("192.168.56.0/24"),
  :publan_start => 131
  },
  {
  :prefix  => "postgres",
  :domain  => "ludovicocaldara.net",
  :box     => "ludodba/ubu1604",
  :nodes   => 1,
  :cpu     => 1,
  :mem     => 2048,
  :publan  => IPAddr.new("192.168.56.0/24"),
  :publan_start => 141
  }
]

###############################
# CUSTOM CONFIGURATION END
###############################

######################################################
# Extending Class IPAddr to add the CIDR to the lan
class IPAddr
  def to_cidr_s
    if @addr
      mask = @mask_addr.to_s(2).count('1')
      "#{to_s}/#{mask}"
    else
      nil
    end
  end
end # extend class IPAddr

########
# MAIN #
########

Vagrant.configure(2) do |config|
  config.ssh.username = "root"  	# my boxes are password based for simplicity
  config.ssh.password = "vagrant"
  config.vm.graceful_halt_timeout = 360	# in case you install grid infra... do not force shutdown after a few seconds

  if File.directory?(sw_path)
    # our shared folder for oracle 12c installation files (uid 54320 is grid, uid 54321 is oracle)
    config.vm.synced_folder sw_path, "/media/sw", :mount_options => ["dmode=775","fmode=775","uid=54322","gid=54328"]
  end

  # looping through each cluster
  (0..(clusters.length-1)).each do |cluid|

    # assign variable clu to current cluster, for convenience
    clu = clusters[cluid]
      
    # looping through each node in the cluster
    (1..(clu[:nodes])).each do |nid|

      # let's start from the last node (see RAC Attack automation for the reason) :-)
      nid = clu[:nodes]+1-nid
      config.vm.define vm_name = "#{clu[:prefix]}%02d" % nid do |cnf|
	  
		# set the right box for the VM
		cnf.vm.box = clu[:box]
		if (clu[:box_version]) then
			cnf.vm.box_version = clu[:box_version]
		end #if
		
		# the new vm name
        vm_name = "#{clu[:prefix]}%02d" % nid
        fqdn = "#{vm_name}.#{clu[:domain]}"
        cnf.vm.hostname = "#{fqdn}"

		# incrementing public ip for the cluster
        pubip = clu[:publan].|(clu[:publan_start]+nid-1).to_s

        cnf.vm.provider :virtualbox do |vb|
          #vb.linked_clone = true  # in case you want thin provisioning. read the vagrant doc before setting it
          vb.name = vm_name
          vb.gui = false
          vb.customize ["modifyvm", :id, "--memory", clu[:mem]]
          vb.customize ["modifyvm", :id, "--cpus",   clu[:cpu]]
          vb.customize ["modifyvm", :id, "--groups", "/#{lab_name}/#{clu[:prefix]}"]
        end #config.vm.provider
		
        # Configuring virtualbox network for #{pubip}
        cnf.vm.network :private_network, ip: pubip

      end #config.vm.define
    end #loop nodes
  end  #loop clusters
end #Vagrant.configure

The nice thing, (beside speeding up the creation and basic configuration) is the organization of the directories. The configuration at the beginning of the script will result in 5 virtual machines:

your VM directory
        |- lab_bigdata 
                |- hadoop
                        |- hadoop01  (ol7)
                        |- hadoop02  (ol7)
                        |- hadoop03  (ol7)
                |- kafka
                        |- kafka01   (ol7)
                |- postgres
                        |- postgres01  (ubuntu 16.04)

It is based, in part (but modified and simplified a lot), from  the RAC Attack automation scripts by Alvaro Miranda.

I have a more complex version that automates all the tasks for a full multi-cluster RAC environment, but if this is your requirement, I would rather check oravirt scripts on github (https://github.com/oravirt) . They are much more powerful and complete (and complex…) than my Vagrantfile. 🙂

Cheers