【Vagrantドキュメント意訳】12.マルチ・マシン

# はじめに

本文章は、Vagrant公式サイト内のドキュメント内の[MULTI-MACHINE](https://www.vagrantup.com/docs/multi-machine/)に記載されている内容を意訳に近い形で日本語化したものである。
誤訳が含まれている可能性が十分にあることを踏まえて、参考いただきたい。

# マルチ・マシン

Vagrantは一つのVagrantfileに複数のゲストマシンを定義し、制御することができる。こらは”マルチ・マシン”環境として知られている。

これらのマシンは一般的に一緒に動作したり、互いに連携したりできる。今日におけるマルチ・マシンの使用方法の一例を示す。

* Webとデータベースサーバを分離するような、マルチ・サーバ・プロダクション・トポロジを正確にモデル化すること
* 分散処理システムのモデル化とどのように互いに影響しあうか
* サービス・コンポーネントへのAPIのような、インタフェースのテスト
* 災害時のテスト：マシンの停止、ネットワークの分断、遅いネットワーク、矛盾した世界観など

歴史的にこのような複雑な環境の稼働は、一つのマシンに押し込めることで行われてきた。この問題は、不正確なプロダクション構築である点で、大きく異なる振る舞いをしてしまう。

Vagrantのマルチ・マシンを使用することで、これらの環境は一つのVagrant環境の文脈でVagrantの恩恵を損なうことなくモデル化出来る。

## マルチ・マシンの定義

マルチ・マシンは、`config.vm.define`メソッド呼出を使用した同じプロジェクトの[Vagrantfile](https://www.vagrantup.com/docs/vagrantfile/)で定義される。この設定のディレクティブは、設定の中でVagrantの設定を生成するため、ややおかしく感じる。この最も適切な例は以下のとおりである。

```bash
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
```

見ての通り、`config.vm.define`は異なる変数をもつブロックを取る。この変数、上記における`web`、は`config`変数と全く同じであり、定義されるマシンだけに適応する内部変数の設定を期待する。そのため、`web`に設定されたものは`web`マシンにのみ影響を及ぼす。

加えて重要なのは、`config`オブジェクトも同様に使用し続けることが出来る点である。設定オブジェクトは、[Vagrantfileロード順](https://www.vagrantup.com/docs/vagrantfile/#load-order)における他のVagrantfileと同じように、マシン特有の設定の前にロードとマージがなされる。

プログラミングに精通しているのであれば、言語がどのように異なる変数スコープを持つか、というのに似ている。

これらのスコープを使用する際、プロビジョナのようなものの実行順は非常に重要なものとなってくる。Vagrantは、Vagrantfile内に列挙されている順番で、外から内の順で実施する。例えば、以下の様なVagrantfileの場合、

```bash
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
```

この場合のプロビジョナは"A"を出力し、その後”C”、さらに”B”をを出力する。”B”が最後である点に注意すること。ファイルに従い、外から内の順番となるためである。

## マルチ・マシンの制御

Vagrantfileで一台以上のマシンが定義されている間、いろいろな`vagrant`コマンドの使用方法は若干変化する。その変化は多くの場合、直感的となっている。

一つのマシンだけを対象することを示唆するコマンド、`vagrant ssh`など、はその時に制御したいマシンの名前が必要である。上述の例を使用して、`vagrant ssh web`や`vagrant ssh db`などが使える。

そのほかのコマンド、`vagrant up`など、はデフォルトですべてのマシンを操作できる。`vagrant up`を実行した場合、VagrantはWebとDBマシンの両方を起動する。`vagrant up web`や`vagrant up db`としてマシンを指定することもできる。

加えて、特定のマシンに一致する正規表現を指定することもできる。これは、例えば`leader`マシンと同様に`follower0`、`follower1`、`follower2`を持つようなサービスを提供するテストを行うような場合などの、多くの類似のマシンがあるような場合に有用である。leader以外のfollowerのすべてを起動したいならば、`vagrant up /follower[0-9]/`を実行するのみである。Vagrantがマシン名にスラッシュを見つけた場合、正規表現が使用されているとみなす。

## マシン間の通信

マルチ・マシン構成でマシン間の通信を容易にするために、さまざまな[ネットワーク]
(https://www.vagrantup.com/docs/networking/)オプションが使用できる。通常、[プライベート・ネットワーク](https://www.vagrantup.com/docs/networking/private_network.html)はマルチ・マシンとホスト間でプライベート・ネットワークを構築するために使うことができる。

## プライマリ・マシンの指定

プライマリ・マシンを指定することができる。マルチ・マシン環境の中で特定のマシンが指定されなかったとき、プライマリ・マシンがデフォルトで使用される。

デフォルトマシンの指定の仕方は、それを定義する際にprimaryを付与するだけである。ただ一つだけのプライマリ・マシンが指定できる。

```bash
config.vm.define "web", primary: true do |web|
  # ...
end
```

## 自動起動マシン

マルチ・マシン環境でのデフォルトでは、`vagrant up`は定義されたすべてのマシンを起動する。`autostart`設定はVagrantに特定のマシンを起動しないことを伝えることができる。

```bash
config.vm.define "web"
config.vm.define "db"
config.vm.define "db_follower", autostart: false
```

上記の設定で`vagrant up`を実行した際、Vagrantは自動的に"web"と"db"マシンを起動するが、"db_follower"を起動しない。`vagrant up db_follower`を実行することで"db_follower"マシンを手動で起動することができる。

# 関連記事

* 前の記事：[【Vagrantドキュメント意訳】11.同期フォルダ](http://qiita.com/ringo0321/items/aec4c543cce63e60a529)
* 次の記事：[【Vagrantドキュメント意訳】13.プロバイダ](http://qiita.com/ringo0321/items/0861cd7e4f630e73164a)