Vagrant is neat if you need a whip up a machine to quickly test a script or check compatibility on an operating system that is different than what you normally run. And the value of that isn’t to be minimized. But some of the real power of Vagrant happens when you start to stand up full environments (think 3-tier applications or large scale web server farms) in a repeatable, effortless way. In Hashicorp Land, this is specifically referred to as a “multi-machine” environment. Any Vagrantfile that defines and controls multiple guest machines qualifies for this descriptor.

Defining Multi-Machine Environments

Building a Vagrantfile that will configure a multi-machine environment is as simple as defining multiple VMs with the parameter config.vm.define. In the below example nabbed from Hashicorp documentation, one case see that an Apache front end and MySQL back end are both defined.

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

Once the VMs are defined, configuration takes place by using the inner variable with the same name. In the example, web. anything and db. anything will apply configurations specifically to that machine. Global configurations can still be defined and will apply to all VMs. When configuring a multi-machine environment, it’s important to consider the load order of a Vagrantfile. I covered this in Part 3 of this series, but just to quickly recap, the load order is:

Vagrantfile packaged with the box that is to be used for a given machine. Vagrantfile in your Vagrant home directory (defaults to ~/.vagrant.d ). This lets you specify some defaults for your system user. Vagrantfile from the project directory. This is the Vagrantfile that you’ll be modifying most of the time. Multi-machine overrides if any. Provider-specific overrides, if any.

As the Vagrantfile grows and a large number of machines are defined, it can become a bit of a mess. Scott Lowe wrote about an idea he found over on this blog that breaks all the configuration data out into a separate YAML file. You could also use JSON or XML if you’re more comfortable with that, as in this example.

Accessing Multi-Machine Environments