【Vagrantドキュメント意訳】07.Vagrantfile

# はじめに

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

# Vagrantfile

Vagrantfileの基本的な機能はプロジェクトに対して要求されるマシンの種類を決定することであり、これらのマシンをどのように設定および供給するかである。Vagrantfilesはそのファイルの文字列で示した実際のファイル名がVagrantfile(厳格なケース・センシティブ・モード内であるファイルシステムが稼働しているのでなければ、ケースは問題ではない)であるためにVagrantfilesと呼ぶ。

Vagrantは一つのプロジェクトあたり一つのVagrantfileで動くことを意味する。そして、Vagrantfileはバージョン制御されることを想定している。これはプロジェクトに関連する他の開発者がコードをチェックアウトし、vagrant upを実行し、独立することを許容する。VagrantfileはVagrantがサポートしているすべてのプラットフォームをまたいで移動することができる。

Vagrantfilesの文法はRubyであるが、最も単純な変数アサインのおかげで、Vagrantfileを変更するためにRubyプログラム言語の知識は必要ではない。事実、Rubyはその中でVagrantが使用されている最も人気のあるコニュニティはではない。これは、Rubyの知識を持っていないにもかかわらず、Vagrantとともにとても成功しているのを示す助けになるだろう。

# 検索パス

いかなるvagrantコマンドを実行する場合においても、Vagrantは初めて見つけることのできるVagrantfileを、カレントディレクトリからディレクトリツリーをたどっていく。/home/mitchellh/projects/fooにおいてvagrantを実行した場合、見つかるまで以下のようにVagrantfileを検索する。

```bash
/home/mitchellh/projects/foo/Vagrantfile
/home/mitchellh/projects/Vagrantfile
/home/mitchellh/Vagrantfile
/home/Vagrantfile
/Vagrantfile
```

この機能はプロジェクト内のどのディレクトリからもvagrantを起動することを可能としている。

VAGRANT_CMD環境変数を、その他のパスに設定することによって、VagrantがどこからVagrantfileを探し始めるか変更することができる。

# 読み込み順とマージ

VagrantがVagrantfilesをどのようにして読み込むかを理解することは、一つの重要な点である。Vagrantは実際には、一式のVagrantfilesを読込、それらの設定をマージする。これは、さまざまなの異なるレベルのVagrantfilesが先の設定を上書きすることを許す。Vagrantfilesはいかに示した順で読み込まれる。それぞれの段階においてVagrantfileが見つからなかった場合、Vagrantはつぎの段階へ移行する。

1. 指定されたマシンのために使用されたたBoxとともにパッケージ化されたVagrantfile。
1. Vagrantホームディレクトリ(デフォルトでは ~/.vagrant.d)内にあるVagrantfile。これはシステムのユーザ用に幾つかのデフォルトを指定することができる。
1. プロジェクトディレクトリ内のVagrantfile。これはその都度修正される様なVagrantfileである。
1. もしあればMulti-machineが上書き
1. もしあればProvider-specificが上書き

それぞれの段階において、それ以前の値で設定値をマージする。これが意味する正確なものは、設定に依存するということである。多くの設定において、新しい設定値が古い設定値を上書きすることを意味する。しかしながら、ネットワークの定義のような項目において、ネットワークはそれぞれの実状に合わせられる。デフォルトでは、設定値はそれぞれによって上書きされることを想定すべきである。もし振る舞いが異なる場合、関連するドキュメント・セクションを参照すること。

それぞれのVagrantfileにおいて、複数のVagrant.configureブロックを指定する。すべての設定は定義された順番において一つのVagrantfileにマージされる。

## コンフィギュレーション・バージョン

コンフィギュレーション・バージョンは、大幅な新しい機能や設定オプションを取り入れる間、Vagrant 1.0.xのVagrantfilesに対してVagrant 1.1以上が後方互換性を残すための機構である。

現時点でvagrant initを実行すると、Vagrantfileはおおまかに以下の様な書式になる。

```bash
Vagrant.configure("2") do |config|
  # ...
end
```

上記における1行目の"2"は設定内容を記述したブロック(doとendで囲まれたセクション)について使用される設定項目のバージョンを示す。この項目はバージョン間で大差がある。

現在、2つだけのバージョンをサポートしている。"1"と"2"である。バージョン1はVagrant 1.0.xの設定を示す。バージョン2は1.1以上2.0.xに至るまでの設定を示す。

Vagrantfilesを読み込むとき、Vagrantはそれぞれのバージョンに対する適切なの設定項目を使用し、そして、その他の設定と同じように、それらを適切にマージする。

一般的なVagrantユーザとして知っておくべき重要な事項は、一つの設定セクション内には、一つのバージョンが使用可能ということである。バージョン1の設定セクション内には、新しいconfig.vm.provider設定を使用することは出来ない。同様にバージョン2設定セクション内のconfig.vm.forward_portは(名前が変更されたため)正しく動作しない。

同じVagrantfiileに複数の設定バージョンを混在させることは可能である。有用な設定スニペットや使いたい何かを発見した場合、この方法は有用である。以下に例示する。

```bash
Vagrant.configure("1") do |config|
  # v1 configs...
end

Vagrant.configure("2") do |config|
  # v2 configs...
end
```

## 最低限のVagrantバージョン

要求されるVagrantのバージョンセットは、あるVagrantfileとともに使用すべき特定のバージョンのVagrantを強制するために、Vagrantfile内で指定することができる。これは古すぎる、または、新しすぎるバージョンのVagrantをあるVagrantfileとともに使用する場合に起こりうる互換性問題の助けとなりうる。

VagrantバージョンはVagrantfileの最も初めの行でVagrant.require_versionで指定する。

```bash
Vagrant.require_version ">= 1.3.5"
In the case above, the Vagrantfile will only load if the version loading it is Vagrant 1.3.5 or greater.
```

複数のバージョンを指定する場合は以下のとおりである。

```bash
Vagrant.require_version ">= 1.3.5", "< 1.4.0"
```

## ヒントと裏ワザ

Vagrantfileはともて柔軟な設定フォーマットを持つ。それは単なるRubyであるためで、多くのことをこなすことができる。しかしながらRubyであるがゆえに、自分自身の足を打つような方法が沢山存在する。このページ内にあるヒントと裏ワザを使用するとき、きちんと正しく使用するように気をつけること。

### VM定義のループ

多くのマルチ・マシンに対して少しだけ異なる設定を適用したい場合、ループを使うことができる。例えば、3つのマシンを生成したい場合

```bash
(1..3).each do |i|
  config.vm.define "node-#{i}" do |node|
    node.vm.provision "shell",
      inline: "echo hello from node #{i}"
  end
end
```

警告：マルチ・マシンの内部の定義とプロバイダの上書きは怠け者のする読込である。これは設定内で変数を使用した値を変更する際に問題を発生させる。例えば、以下のループは正しく動作しない。

```bash
# THIS DOES NOT WORK!
for i in 1..3 do
  config.vm.define "node-#{i}" do |node|
    node.vm.provision "shell",
      inline: "echo hello from node #{i}"
  end
end
```

Rubyにおける ```for i in ...``` 構造は、実際にはiの値をそれぞれの繰り返しの中でコピーをするよりも、むしろ更新する。そのためこれを実行した場合、実際にはすべてのノードは同じテキストで供給される。

これは単純な誤りであり、そしてVagrantはこれに対して回避することが出来ない。ここで取るべき最善策について言及する。

### SSHセッションにおけるホスト・ロケールの上書き

通常、ホスト・ロケール環境変数はゲストに受け渡される。ゲストのソフトウェアがホスト・ロケールをサポートしていない場合、これは失敗となる。一つの解決方法は、Vagrantfile内でロケールを上書きする方法である。

```bash
ENV["LC_ALL"] = "en_US.UTF-8"

Vagrant.configure("2") do |config|
  # ...
end
```

この変更はVagrantfile内でしか見ることは出来ない。

## マシン設定

### 設定名前空間：config.vm

config.vm内の設定はVagrantが管理しているマシンの設定を変更する。

### 適応可能な設定

#### config.vm.boot_timeout

Vagrantの起動とアクセス可能となるまでの待ち時間を秒で時間指定する。デフォルトは300秒である。

#### config.vm.box

そのマシンのBoxが何であるかを設定する。この値はインストールされたBoxの名前、もしくは、HashiCorpのAtlas内にあるBoxの省略した名前である。

このオプションはVagrant 1.5以上であることを要求する。Vagrantの最新バージョンはVagrantインストーラ・ページからダウンロードすることができる。

#### config.vm.box_check_update

trueが指定された場合、Vagrantはvagrant upの度に設定しているBoxのアップデートを確認する。アップデートが見つかると、Vagrantはユーザに通知する。デフォルトではこれはtrueである。アップデートは適切なサポートのBoxのアップデートに対してのみ行われる（HashiCorpのAtlasやその他のバージョン管理されたBox）。

#### config.vm.box_download_checksum

Boxのチェックサムはconfig.vm.box_urlによって指定される。指定されていない場合、チェックサム比較は行われない。指定されている場合、VagrantはダウンロードしたBoxのチェックサムとこの値を比較し、一致しなければエラーとする。チェックサムの確認はVagrantがBoxをダウンロードすべき時にのみ行われる。

これが指定された場合、config.vm.box_download_checksum_typeを合わせて設定する必要がある。

#### config.vm.box_download_checksum_type

config.vm.box_download_checksumによって指定されたチェックサムの種類を指定する。サポートする値は、現在"md5"、"sha1"、"sha256"である。

#### config.vm.box_download_client_cert

Boxをダウンロードする際に使用されるクライアント証明書のためのパスを、必要に応じて指定する。デフォルトでは、Boxのダウンロードにクライアント証明書は使用しない。

#### config.vm.box_download_ca_cert

Boxを直接ダウンロードする際に使用するCA証明書バンドルへのパスを指定する。デフォルトではVagrantはMozilla CA証明書バンドルを使用する。

#### config.vm.box_download_ca_path

Boxを直接ダウンロードする際にCA証明書のあるディレクトリへのパスを指定する。デフォルトではVagrantはMozilla CA証明書バンドルを使用する。

#### config.vm.box_download_insecure

trueを指定した場合、サーバからのSSL証明書を検証しない。デフォルトでは、URLがHTTPS URLであれば、SSL証明書を検証する。

#### config.vm.box_download_location_trusted

trueを指定した場合、すべてのHTTPリダイレクトを信頼されたものとして取扱う。これは、すべてのリダイレクトされたサブ・シーケンスに対する一番初めのURLのために、資格情報が使用されることを意味する。デフォルトでは、リダイレクト・ロケーションは信頼されず、(指定されている場合)資格情報は初めのHTTPリクエストに対してのみ使用される。

#### config.vm.box_url

設定しているBoxがあるURLを指定する。もし、config.vm.boxがHashiCorpのAtlas内の省略されたBoxであれば、この値は指定する必要はない。しかし、インストールされていない場合、Boxがある適切な場所を示す必要がある。

これは複数のURLの列挙を行うことができる。URLはその順に試行される。クライアント証明書、因セキュア・ダウンロードの設定などはこのリストのURL全てに適用される点に注意すること。

URLはfile://スキーマを使用することでローカルファイルについても指定できる。例）``` "file:///tmp/test.box".```

#### config.vm.box_version

使用するBoxのバージョンを指定する。デフォルトでは```">= 0"```(入手できる最新)である。これはコンマによって分離された任意の制約リストを含むことができる。たとえば、```>= 1.0, < 1.5```のように。 制約が指定された場合、Vagrantはその制約を満たす入手可能な最新のものを使用する。

#### config.vm.communicator

ゲストBoxに接続するために使用するコミュニケータの種類を指定する。デフォルトでは"ssh"であるが、Windowsゲストの場合"winrm"に変更すべきである。

#### config.vm.graceful_halt_timeout

vagrant haltが呼ばれた際に、マシンがきちんと停止するまでのVagrantの待ち時間を秒で指定する。デフォルトは60秒である。

#### config.vm.guest

マシン上で稼働するゲストOSを指定する。デフォルトは```:linux```である。Vagrantは適切なディストリビューションを自動的に検出することもできる。Vagrantはフォルダのマウントやネットワークの設定など、ゲストOS特有の内容に対して適応するための情報を知るために必要である。

#### config.vm.hostname

マシンが持つべきホスト名を指定する。デフォルトはnilである。nilである場合、Vagrantはホスト名を管理しない。文字列が設定された場合、ブート時にホスト名として設定される。

#### config.vm.network

マシンのネットワークの設定を指定する。より詳細な情報については、ネットワークの項を参照のこと。

#### config.vm.post_up_message

vagrant upした後に表示するメッセージを指定する。これはユーザが見ることが出来、開発環境の様々なコンポーネントにどのようにアクセスするかなどの指示を含ませるなどに有用である。

#### config.vm.provider

プロバイダ特有の設定を指定する。特定のプロバイダに対して指定すべき設定の変更などに使用する。設定しているプロバイダが存在しない、または、ある人がvagrant upによって稼働したシステム上では構築されていない等の場合、Vagrantはこの設定ブロックを無視する。これはすべてに同じプロバイダがインストールされているわけではない人々のグループの間で共有された様々なプロバイダに対する設定を持つようなVagrantfileを許容する。

#### config.vm.provision

マシン上のプロビジョナを設定する。マシンが生成された時、それらのソフトウェアを自動的にインストール出来、また、設定することができる。この設定がどのように動くかに関するより詳細な情報はプロビジョナの項を参照のこと。

#### config.vm.synced_folder

マシン上の同期フォルダを設定する。ホストマシン上のそのフォルダはゲストマシンとの間で同期される。この設定がどのように動くかに関するより詳細な情報は同期フォルダの項を参照のこと。

#### config.vm.usable_port_range

ポートの衝突などを処理するために使用することができる、ポートの範囲を指定する。デフォルトでは2200から2250である。

## SSH設定

### 設定名前空間：config.ssh

config.ssh内の設定はVagrantがSSHを経由してマシンにどのようにアクセスするかである。おおくのVagrant設定のように、デフォルトでも概して問題ない。しかし、好きなように調整することが可能である。

### 適用可能な設定

#### config.ssh.username

これはデフォルトとしてVagrantがSSHする際のユーザ名を設定する。プロバイダがより適切なユーザを検出した場合、それを上書きすることは自由である。公開されているBoxの多くがそうであるように、デフォルトではこれは”vagrant"である。

#### config.ssh.password

これはVagrantがSSHユーザを認証するために使用されるパスワードを設定する。Vagrantはパスワードよりも鍵ベースの認証を使用することを推奨している（private_key_pathを参照)。パスワードを使う場合、insert_keyがtrueであれば、Vagrantは自動的に鍵ペアを挿入する点に注意すること。

#### config.ssh.host

SSHする先のホスト名またはIPを指定する。プロバイダが見つけ出すため、デフォルトではこれは空である。

#### config.ssh.port

SSHを行うポート番号を指定する。デフォルトでは22番ポートである。

#### config.ssh.guest_port

SSHが稼働しているゲスト上のポートである。いくつかのプロバイダがSSH用の転送ポートを検出するために、これを使用する。例えば、22(デフォルト)に設定された場合、Vagrantはホスト上の4567番ポートからゲスト上の22番ポートへ転送されたことを演出する。Vagrantは、そのほかに何もオプションがなければ、4567番ポートを使用して通信しようと試みる。

#### config.ssh.private_key_path 

ゲストマシンにSSHする際に使用する秘密鍵へのパスを指定する。公開Boxを使用しているため、デフォルトではVagrantに搭載されている非安全な秘密鍵である。カスタムしたSSH鍵を持つカスタムBoxを作りたければ、秘密鍵をポイントするべきである。

この項目を配列で設定することで複数の秘密鍵を指定することもできる。これは、例えば、マシンを起動する際にデフォルトの秘密鍵を使用するが、その後、より安全な鍵によって置き換えるかもしれない場合に有用である。

#### config.ssh.forward_agent

trueに設定された場合、エージェントはSSH接続のフォワーディングを可能とする。デフォルトではfalseである。

#### config.ssh.forward_env

ゲストに転送されるホストの環境変数の配列である。OpenSSHに詳しいなら、これはSendEnvパラメータに相当する。

```bash 
config.ssh.forward_env = ["CUSTOM_VAR"]
```

#### config.ssh.insert_key

trueが設定された場合、VagrantはSSHを使用する際に、それがマシン内部で検出された場合、Vagrantのデフォルトの非安全な鍵ペアを自動的に挿入する。デフォルトではtrueである。

これは、認証に対してまだ秘密鍵を使用していない場合や、デフォルトの非安全な鍵を使用している場合にのみ硬貨を発揮する。プロジェクトにおいて安全を考慮する必要が無い場合や、デフォルトの非安全な鍵を使用し続ける場合は、これをfalseに設定する。

#### config.ssh.proxy_command

SSHに送りたいデータを標準入力から受け取る様なコマンドラインのコマンドを指定する。これはSSH接続にプロキシを使用することができる。このコマンド内の%hはホストに、%pはポートに置き換えられる。

#### config.ssh.pty

trueが設定された場合、ptyはプロビジョニングのために使用される。デフォルトではfalseである。

この設定は、絶対に必要である場合でないかぎりは有効にすべきでない、高度な機能である。これはVagrantのその他の幾つかの機能を破壊する。また、これは絶対的に必要である場合のためだけに使用する。もし、ptyを使用しない方法を見つけた場合、それをこの設定の代わりとすることを推奨する。

#### config.ssh.shell

VagrantからSSHコマンドを実行する際に使用するShellを設定する。デフォルトでは```bash -l```である。これは```vagrant ssh```によって得られるshellに対してはなんの影響も与えないことに中止すること。これはVagrant内部でコマンドを実行する際に使用されるshellに影響をおよぼすだけの設定である。

#### config.ssh.sudo_command

```sudo```でコマンドを実行する際に使用するコマンドを設定する。デフォルトでは```sudo -E -H %c```である。```%c```は実行されるべきコマンドによって置き換えられる。

## WINRM設定

### 設定名前空間：config.winrm

config.winrmにて設定されるのはVagrantがWinRMを通じてWindowsにどのようにアクセスするかを設定する。おおくのVagrant設定のように、デフォルトは一般的に適切なものとなっている。しかし、好きなように調整することができる。

これらの設定はコミュニケータの種類がwinrmである場合のみに使用される。

### 適用可能な設定

#### config.winrm.username

VagrantがデフォルトでWinRMウェブサービスにログインする際に使用するユーザ名を設定する。より適切なユーザを検出した場合、プロバイダが上書きすることは自由である。多くに公開Boxでそうあるように、デフォルトでは"vagrant"である。 

#### config.winrm.password

WinRMユーザの認証のためにVagrantが使用するパスワードを設定する。多くの公開Boxがそうあるように、デフォルトでは"vagrant"である。

#### config.winrm.host

WinRMサービスに接続するためのホスト名まはたIPである。通常プロバイダはそれを見つけ出すため、デフォルトでは空になっている。

#### config.winrm.port

WinRMに接続する際のポート番号である。デフォルトでは5985である。

#### config.winrm.guest_port

WinRMが稼働しているゲスト上のポート番号である。これはWinRMのために転送するポートを決定する際にいくつかのプロバイダによって使用される。たとえば、これを5985(デフォルト値)に設定した場合、Vagrantはホスト上の4567番ポートからゲスト上の5985番ポートへの転送ポートを検出し、Vagrantは、ほかの選択肢がなければ、4567番ポートをゲストとの通信をするために使用することを試みる。

#### config.winrm.transport

WinRM通信のために使用する転送を設定する。有効な設定値は、negotiate、ssl、plaintextである。デフォルトでは、negotiateである。

#### config.winrm.basic_auth_only

ベーシック認証を使用するかどうかを指定する。デフォルトではfalseである。もしtrueに設定する場合は、転送設定(config.winrm.transport)もあわせてplaintextにし、さらにWindowsマシンも適切に設定されている必要がある。デバッグ目的のためにはベーシック認証を使用することのみを強く推奨する。証明書が平文で転送されるためである。

#### config.winrm.execution_time_limit

WinRMタスクが実行された際の最大の持続時間を設定する。デフォルト値は2時間である。この値のフォーマットは、この[マイクロソフト文書フォーマット](https://msdn.microsoft.com/en-us/library/aa382678.aspx)の値でなければならない。

## Vagrant設定

### 設定名前空間：config.vagrant

config.vagrant内の設定はVagrant自身の振る舞いを変更する。

### 適用可能な設定

#### config.vagrant.host

Vagrantが稼働するホストマシンの種類を設定する。デフォルトではdetectである。この場合、Vagrantがホストを自動検出する。Vagrantはホスト特有の動作のために、たとえば有効に設定されている場合に事前にNFSフォルダを用意するなど、この情報を知る必要がある。自動検出が失敗するときにだけ、手動で設定するべきである。

# 関連記事

* 前の記事：[【Vagrantドキュメント意訳】06.Vagrant共有](http://qiita.com/ringo0321/items/224150c93f2930eec54a)
* 次の記事：[【Vagrantドキュメント意訳】08.Box詳細](http://qiita.com/ringo0321/items/f76da11503c627205c52)