2

I created a VM with some server settings and customizations and used vagrant to create a box. I imported the box into vagrant so I can spin up more than one server with the same configuration.

Also created a VM with client settings and boxed it with vagrant so I could create multiple clients.

I want to know whether it is possible to have in the same Vagrantfile a block of code for the server using the server_box and a block of code for the client using the client_box. I though I could use a config.vm.box for each but when I spin up the VMs, the clients pick up the client_box image, which is what I want, but the server also picks up the client_box image ignoring its own setting.

My attempt is below. NOTE: I know I can use a loop to create a series of clients. I just put the code as below for simplicity and clarity.

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "server_box"
  config.vm.define "server1", primary: true do |server1|
    [...vm specs here...]
  end
end


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "client_box"

  config.vm.define "client1", autostart: false do |client1|
    [...vm specs here...]
  end

  config.vm.define "client2", autostart: false do |client2|
    [...vm specs here...]
  end

end
Lun
  • 21
  • 3
  • Is there a reason you couldn't just put all the boxes within a single Vagrant.configure block and then override the boxes in the usual manner by doing `server1.vm.box = "server_box"` and so on? I.E. the approach outlined at http://docs.vagrantup.com/v2/multi-machine/index.html ? – Ruaidhrí Primrose Jun 22 '15 at 14:15
  • I had read the info in the link. Yes, in a single block, you can first put the line **config.vm.box = "server_box"** and spin up the server, then edit the Vagrantfile and change the line to **config.vm.box = "client_box"** to spin up the clients, but that's not much in the way of automation as I envision it. I wish it would be more seamless. Now, it would be more interesting if the Vagrantfile took command line arguments to make it more dynamic; have vars like config1.vm.box, config2.vm.box and at the CLI say --config1=server_box, --config2=client_box. – Lun Jun 23 '15 at 14:41
  • But you can overload config.vm.box for each machine? I.E. for the server VM you specify `server.vm.box ="server_box"`, for client 1 you specify `client1.vm.box="client_box"`, for client 2 you specify `client2.vm.box="client_box` etc. Is that not working for you? From the link "As you can see, config.vm.define takes a block with another variable. This variable, such as web above, is the exact same as the config variable, except any configuration of the inner variable applies only to the machine being defined. Therefore, any configuration on web will only affect the web machine." – Ruaidhrí Primrose Jun 24 '15 at 08:36

1 Answers1

2

Yes, you can specify multiple machines by using the config.vm.define method call, e.g.

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo Hello"

  config.vm.define "web" do |web|
    web.vm.box = "apache"
  end

  config.vm.define "db" do |db|
    db.vm.box = "mysql"
  end
end

See: Defining multiple machines at Vagranup Docs


You can also use a switch case syntax, so you can set box depending on some variable, e.g.

case provider
  when "virtualbox"
    config.vm.box = "ubuntu/wily64"
  when "aws"
    config.vm.box = "dummy"
end

Alternatively set the web.vm.box based on the environment variable, e.g.

config.vm.box = ENV['BOX']

and provide the value from the command line, like:

BOX=server_box vagrant up

See also: Multiple provisioners in a single vagrant file?

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743