summaryrefslogtreecommitdiff
path: root/devdocs/vagrant/multi-machine.html
blob: d8ecf760856769d02feca62ac670d3bc7c45058f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<h1 id="multi-machine">  Multi-Machine </h1> <p>Vagrant is able to define and control multiple guest machines per Vagrantfile. This is known as a "multi-machine" environment.</p> <p>These machines are generally able to work together or are somehow associated with each other. Here are some use-cases people are using multi-machine environments for today:</p> <ul> <li>Accurately modeling a multi-server production topology, such as separating a web and database server. </li> <li>Modeling a distributed system and how they interact with each other. </li> <li>Testing an interface, such as an API to a service component. </li> <li>Disaster-case testing: machines dying, network partitions, slow networks, inconsistent world views, etc. </li> </ul> <p>Historically, running complex environments such as these was done by flattening them onto a single machine. The problem with that is that it is an inaccurate model of the production setup, which can behave far differently.</p> <p>Using the multi-machine feature of Vagrant, these environments can be modeled in the context of a single Vagrant environment without losing any of the benefits of Vagrant.</p> <h2 id="defining-multiple-machines">  Defining Multiple Machines </h2> <p>Multiple machines are defined within the same project <a href="vagrantfile/index">Vagrantfile</a> using the <code>config.vm.define</code> method call. This configuration directive is a little funny, because it creates a Vagrant configuration within a configuration. An example shows this best:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">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
</pre></div>
<p>As you can see, <code>config.vm.define</code> takes a block with another variable. This variable, such as <code>web</code> above, is the <em>exact</em> same as the <code>config</code> variable, except any configuration of the inner variable applies only to the machine being defined. Therefore, any configuration on <code>web</code> will only affect the <code>web</code> machine.</p> <p>And importantly, you can continue to use the <code>config</code> object as well. The configuration object is loaded and merged before the machine-specific configuration, just like other Vagrantfiles within the <a href="vagrantfile/index#load-order">Vagrantfile load order</a>.</p> <p>If you are familiar with programming, this is similar to how languages have different variable scopes.</p> <p>When using these scopes, order of execution for things such as provisioners becomes important. Vagrant enforces ordering outside-in, in the order listed in the Vagrantfile. For example, with the Vagrantfile below:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">Vagrant.configure("2") do |config|
  config.vm.provision :shell, inline: "echo A"

  config.vm.define :testing do |test|
    test.vm.provision :shell, inline: "echo B"
  end

  config.vm.provision :shell, inline: "echo C"
end
</pre></div>
<p>The provisioners in this case will output "A", then "C", then "B". Notice that "B" is last. That is because the ordering is outside-in, in the order of the file.</p> <p>If you want to apply a slightly different configuration to multiple machines, see <a href="vagrantfile/tips#loop-over-vm-definitions">this tip</a>.</p> <h2 id="controlling-multiple-machines">  Controlling Multiple Machines </h2> <p>The moment more than one machine is defined within a Vagrantfile, the usage of the various <code>vagrant</code> commands changes slightly. The change should be mostly intuitive.</p> <p>Commands that only make sense to target a single machine, such as <code>vagrant ssh</code>, now <em>require</em> the name of the machine to control. Using the example above, you would say <code>vagrant ssh web</code> or <code>vagrant ssh db</code>.</p> <p>Other commands, such as <code>vagrant up</code>, operate on <em>every</em> machine by default. So if you ran <code>vagrant up</code>, Vagrant would bring up both the web and DB machine. You could also optionally be specific and say <code>vagrant up web</code> or <code>vagrant up db</code>.</p> <p>Additionally, you can specify a regular expression for matching only certain machines. This is useful in some cases where you specify many similar machines, for example if you are testing a distributed service you may have a <code>leader</code> machine as well as a <code>follower0</code>, <code>follower1</code>, <code>follower2</code>, etc. If you want to bring up all the followers but not the leader, you can just do <code>vagrant up /follower[0-9]/</code>. If Vagrant sees a machine name within forward slashes, it assumes you are using a regular expression.</p> <h2 id="communication-between-machines">  Communication Between Machines </h2> <p>In order to facilitate communication within machines in a multi-machine setup, the various <a href="networking/index">networking</a> options should be used. In particular, the <a href="networking/private_network">private network</a> can be used to make a private network between multiple machines and the host.</p> <h2 id="specifying-a-primary-machine">  Specifying a Primary Machine </h2> <p>You can also specify a <em>primary machine</em>. The primary machine will be the default machine used when a specific machine in a multi-machine environment is not specified.</p> <p>To specify a default machine, just mark it primary when defining it. Only one primary machine may be specified.</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">config.vm.define "web", primary: true do |web|
  # ...
end
</pre></div>
<h2 id="autostart-machines">  Autostart Machines </h2> <p>By default in a multi-machine environment, <code>vagrant up</code> will start all of the defined machines. The <code>autostart</code> setting allows you to tell Vagrant to <em>not</em> start specific machines. Example:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">config.vm.define "web"
config.vm.define "db"
config.vm.define "db_follower", autostart: false
</pre></div>
<p>When running <code>vagrant up</code> with the settings above, Vagrant will automatically start the "web" and "db" machines, but will not start the "db_follower" machine. You can manually force the "db_follower" machine to start by running <code>vagrant up db_follower</code>.</p><div class="_attribution">
  <p class="_attribution-p">
    &copy; 2010&ndash;2018 Mitchell Hashimoto<br>Licensed under the MPL 2.0 License.<br>
    <a href="https://www.vagrantup.com/docs/multi-machine" class="_attribution-link">https://www.vagrantup.com/docs/multi-machine</a>
  </p>
</div>