55

I need to run several boxes with Vagrant.

Is there a way to do that?

These don't relate one to another in any way, they can be thought as different environments using for test so it seems that multi-machine setup has nothing to do with this.

timurb
  • 5,405
  • 2
  • 22
  • 17

7 Answers7

55

The best way is to use an array of hashes. You can define the array like:

servers=[
  {
    :hostname => "web",
    :ip => "192.168.100.10",
    :box => "saucy",
    :ram => 1024,
    :cpu => 2
  },
  {
    :hostname => "db",
    :ip => "192.168.100.11",
    :box => "saucy",
    :ram => 2048,
    :cpu => 4
  }
]

Then you just iterate each item in server array and define the configs:

Vagrant.configure(2) do |config|
    servers.each do |machine|
        config.vm.define machine[:hostname] do |node|
            node.vm.box = machine[:box]
            node.vm.hostname = machine[:hostname]
            node.vm.network "private_network", ip: machine[:ip]
            node.vm.provider "virtualbox" do |vb|
                vb.customize ["modifyvm", :id, "--memory", machine[:ram]]
            end
        end
    end
end
Robin Daugherty
  • 7,115
  • 4
  • 45
  • 59
david
  • 641
  • 6
  • 2
40

You can definitely run multiple Vagrant boxes concurrently, as long as their configuration does not clash with one another in some breaking way, e.g. mapping the same network ports on the host, or using same box names/IDs inside the same provider. There's no difference from having multiple boxes running on a provider manually, say multiple boxes on VirtualBox, or having them registered and started up by Vagrant. The result is the same, Vagrant just streamlines the process.

You can either use so called multi-machine environment to manage these boxes together in one project/Vagrantfile. They don't necessarily have to be somehow connected, ease of management may be the reason alone, e.g. if you need to start them up at the same time.

Or you can use separate projects/Vagrantfiles and manage the machines from their respective directories, completely separated.

In case of running multiple instances of the same project, you need multiple copies of the project directory, as Vagrant stores the box state in the .vagrant directory under the project.

famousgarkin
  • 13,687
  • 5
  • 58
  • 74
  • Thanks! Just copying the dir with Vagrantfile to some other location works fine. I think I've missed something when I've tried to do that last time. – timurb May 28 '14 at 12:46
  • 4
    Just to further clarify: is there a way to run several independent Vagrant environments from a single Vagrantfile without copying it or is it the recommended process to have one Vagrantfile per environment? – timurb May 28 '14 at 12:49
  • 2
    @erthad Ah, I see, now the question makes a lot more sense :) Yes, in that case you need multiple copies of the same project, as Vagrant stores the box state in the `.vagrant` directory under the project. Adding to the answer. – famousgarkin May 29 '14 at 07:16
  • 1
    One way to simulate multiple copies of the same directory is to use git branches. Give each branch its own version of the .vagrant directory, et voila. This can also be used in a CI/CD context if you need to provision a server for automated building or testing but need to isolate your branches. – Stuporman Jul 02 '16 at 01:05
22

You need just to copy the directory holding Vagrantfile to the new place and run vagrant up from it.

Make sure you copy the dir prior to starting up the box for the first time or Vagrant will think that these two locations refer to the same box. Or, if you already did vagrant up before copying the directory, then delete copied_directory/.vagrant after you make the copy.

David Winiecki
  • 4,093
  • 2
  • 37
  • 39
timurb
  • 5,405
  • 2
  • 22
  • 17
17

You can even use different Vagrantfile(s) in same directory for different machine configuration or boxes

VAGRANT_VAGRANTFILE=Vagrantfile.ubntu_1404_64 VAGRANT_DOTFILE_PATH=.vagrant_ub140464 vagrant up

OR

VAGRANT_VAGRANTFILE=Vagrantfile.ubntu_1404_32 VAGRANT_DOTFILE_PATH=.vagrant_ub140432 vagrant up

Both the Vagrantfile can reside in same directory

deepdive
  • 9,720
  • 3
  • 30
  • 38
  • precise and to the point. Additional note, on windows, apparently we still can't set variables per command. Need to run set = before vagrant up – shiva Jan 26 '17 at 18:54
5

I was able to have a single vagrantfile:

Vagrant.configure("2") do |winconfig|
 # stuff
end

Vagrant.configure("2") do |nixconfig|
 # stuff
end

Vagrant.configure("2") do |macconfig|
 # stuff
end

and then I can bring them up with vagrant up --parallel. As others have mentioned, different vagrant files may be better for maintainability.

Zach Folwick
  • 893
  • 10
  • 18
4

https://www.vagrantup.com/docs/vagrantfile/tips.html#loop-over-vm-definitions

(1..3).each do |i|
  config.vm.define "node-#{i}" do |node|
    node.vm.provision "shell",
      inline: "echo hello from node #{i}"
  end
end
030
  • 10,842
  • 12
  • 78
  • 123
  • 1
    I've had some trouble with this pattern (Ansible 2 on Windows). When I create the boxes in a loop like this, 'vagrant destroy' can only find one of the 3 boxes in the example above. I have to manually destroy the remaining 3 boxes in the Virtualbox UI itself. Anyone else experiencing this? Is it a bug, or user error? Can confirm that 'hardwiring' the instances works as expected though. – Charlie Aug 06 '18 at 15:11
  • I used this pattern today on windows using the Virtualbox provider and 'vagrant destroy --force' destroyed each of the nodes for me. Imo this is the most elegant solution, specifically if you need multiple VMs with similar setting. – Brandon McClure Dec 28 '20 at 04:00
0

Copying the directory holding Vagrantfile to a new place and spinning up the new machine there is the most straight forward way, if machines are not co-operating.

However, you may not want to copy/paste provisioning scripts for VCS tracking/backtracking purposes. Keep all your scripts in a folder, ex. dev, and put your Vagrantfile under numbered folders under dev, ex. dev/10. When you create a newer version, ex. dev/11 and not need the older one, you may just delete it. And refer to the common provisioning scripts using relative path:

config.vm.provision "shell", path: "../provisioner.sh"
mehmet
  • 7,720
  • 5
  • 42
  • 48