【Vagrantドキュメント意訳】08.Box

# はじめに

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

# Box

BoxはVagrant環境用のパッケージ・フォーマットである。BoxはVagrantがサポートしているどんなプラットフォームでも同じ環境が動作するよう、誰でも使用することができる。

VagranのBoxの有用性はBoxを管理するためのすべての機能を提供することである。vagrant boxコマンドのドキュメントでより詳細について読むことができる。

Boxを使うもっとも簡単な方法は、公開されている入手可能なVagrant Boxのカタログから追加することだろう。このWebサイト上でカスタマイズしたBoxを追加し、共有することもできる。

BoxはVagrantを使用しているチームのメンバーが容易にBoxに基づいてアップデートできるようにバージョン管理もサポートしている。そして、Boxを作った人がバグfix版をpushしたり、これらのfixを効果的に伝えることができる。

## Boxを知る

Boxを理解する最も簡単な方法は、公開されているVagrant Boxカタログから使う状況に適したものを見つけることである。カタログには多くの主要なオペレーティング・システムを基にしたものが含まれ、専用のBoxを得ることができ、LAMPスタックやRuby、Pythonなどを素早く動かせる。必要なBoxを見つけることができるだろう。

カタログからBoxを追加するのは簡単である。それぞれのBoxにはどのように追加するかの説明があるが、たいてい次のような書式である。

```bash
$ vagrant box add USER/BOX
```

例

```bash
vagrant box add hashicorp/precise64
```

同様に

```bash
vagrant init hashicorp/precise64
```

でVagrant環境を素早く初期化できる。

名前空間は標準的なBoxを保証するものではない。よくある誤解しやすい点は、"ubuntu"のような名前空間がUbuntuのBoxを保証する空間であることを示す、ということである。これは真実ではない。Atlas上の名前空間は、たとえばGitHub上の名前空間と非常によく似た振る舞いをする。ちょうどGitHubのサポートチームが誰かしらのリポジトリ内の課題の手助けをすることが出来ないのと同様に、HashiCorpのサポートチームはサード：パーティが公開したBoxの手助けをすることは出来ない。

# BOXのバージョン管理

Vagrant 1.5から、Boxはバージョン管理をサポートしている。これによってBoxを作成した人がBoxへのアップデートをpushでき、Boxを使用している人がアップデートを確認するための簡単なワークフロー、つまり、Boxをアップデートし、何が変更されたかをみるための方法を手にすることができる。

Vagrantを始めたばかりなら、Boxのバージョン管理はさほど重要ではない。また、その他のトピックについて先に学ぶことをおすすめする。しかし、チーム内でVagrantを使用する、または、自身でBoxを作ろうと考えているならば、バージョン管理は非常に重要である。幸運にも、Vagrantでの正しいバージョン管理方法は、簡単に使えるように、また、Vagrantワークフロー内によく適応するようになっている。

ここではバージョン管理したBoxの使い方を対象とする。バージョン管理された自身のカスタムBoxをどのようにアップデートするかについては対象外とする。後者についてはBase Boxの生成において示す。

## バージョンの閲覧とアップデート

`vagrant box list`はインストールされたBoxのバージョンのみ表示する。入手可能なすべてのBoxのバージョンを見るには、HashiCorpのAtlas内からBoxを見つける必要がある。Boxを見つけるための一つの簡単な方法は、このようなURL https://atlas.hashicorp.com/$USER/$BOX を使用することである。例えば、hashicorp/precise64 のBoxの場合、 https://atlas.hashicorp.com/hashicorp/precise64 でその情報を見ることができる。

使用しているBoxが古くなっていた場合、`vagrant box outdated`によってそれを確認することができる。これは、システム上にインストールされたその他のBoxと同様に、現在のVagrant環境のBoxが古くなっているかを確認することができる。

そして、`vagrant box update`によってBoxをアップデートすることができる。これにより新しいBoxをダウンロードし、インストールを行う。これは稼働中のVagrant環境をアップデートする便利なものではない。Vagrant環境がすでに稼働していれば、Boxの新しいアップデートを取得するために`destroy`と`recreate`を行う必要がある。`update`コマンドは、単にこれらのアップデートをローカルにダウンロードするだけである。

## バージョン強制

Vagrantfileのconfig.vm.box_versionオプションによって、特定のバージョンやBoxのバージョンをVagrant環境に強制することができる。

このオプションが指定されていない場合、常に最も新しいバージョンが使用される。これは">= 0"の強制を指定することと同等である。

Boxバージョンの設定は、バージョンの指定やバージョンの強制ができる。強制は以下の様な組み合わせによって適応する。 = X, > X, < X, >= X, <= X, ~> X。また、コンマによって区切ることで複数の強制の組み合わせができる。”悲観的な強制”として知られる ~> を除いて、それぞれの強制はその記号の示す通りだと理解できるだろう。この ~> の最も適切な説明としては、 ~> 1.0 は、>= 1.0, < 2.0 と等価であり、~> 1.1.5 は >= 1.1.5, < 1.2.0 と等価である。

バージョンの扱いは適切に選択することができる。しかしながら、公開されているカタログ内の多くのBoxは、意味のあるバージョン記法に従っている。基本的には、最も左側の番号（メジャー・バジョン）が違う場合、後方互換性を維持しない。これはVagrant Boxにおいて、バージョン"1.1.5"のBox上で稼働していたいかなるソフトウェアも、"1.2"や"1.4.5"などでも稼働することを意味する。 しかし"2.0"は大きな変更を示唆するため保証されない。これらの規則に従うことで、その範囲内にあるバージョンが安全で問題ないことが自明であるため、最も適切な強制は　~> 1.0 という形である。

バージョン記法においては、3つ以上のポイントとプレ・リリースやベータバージョンを許しているのに対して、Vagrant Boxは、X、Y、Zを整数値として、X.Y.Zの書式であるべきという点には注意が必要である。

## アップデートの自動確認

Vagrantfileを用いることで、Vagrantが自動的に`vagrant up`されている間にアップデートを確認することも可能である。これはデフォルトでは有効となっている。しかし、Vagrantfile内で`config.vm.box_check_update = false`とすることで簡単に無効にすることができる。

これが有効である場合、Vagrantはマシンが新たに生成された時だけでなく、レジュームされた時、停止して再起動した時など、`vagrant up`毎に毎回アップデートを確認する。

アップデートが見つかった場合、Vagrantはアップデートが入手可能であることをユーザに対して警告表示を行う。ユーザはその警告に対して、その時点では拒否するか、`vagrant box update`を実行することでBoxのアップデートを行なうかを選択することができる。

Vagrantは自動的にアップデートのBoxをダウンロードしマシンをアップデートすることは出来ない。Boxのサイズは比較的大きく、また、マシンをアップデートすることはマシンの`destroy`と`recreate`が必要であり、これはデータ消失の重大なる原因となり得るからである。そのため、この処理はユーザーが手動でコマンドを入力しなければならない。

## 古いバージョンの除去

Vagrantは、Boxがその他のVagrant環境によって使用されるかを知り得ないため、自動的に古いバージョンを除去しない。また、Boxのサイズは大きいため、`vagrant box remove`を使用して時折それら古いバージョンを除去する方が良いだろう。`vagrant box list`を用いることでインストールされているBoxを見ることができる。

# Base Boxの生成

"Base Box"として知られる特殊なカテゴリのBoxがある。これらのBoxはVagrantが機能するために要する最小の素の状態であり、通常、既存のVagrant環境を再パッケージすることで生成されるものではない(そのため"Base"という）。

例えば、("precise64"などのような）Vagrantプロジェクトによって提供されているUbuntuのBoxはBase Boxである。それらは、既存の環境を再パッケージするのではなく、ISOから最小のUbuntuをインストールしたものから作られている。

Base Boxは、あらたな開発環境を構築する起点としてまっさらな状態を手に入れるために極めて有用である。Vagrantプロジェクトは、将来的により多くのオペレーティング・システムに対してBase Boxを提供したいと考えている。それまでは、この文書によって、どのように自身のBase Boxを生成するかを提示したいと思う。

> 上級者向け：Base Boxを生成することは多くの時間を費やし、退屈な処理であるので、新しいVagrantユーザにはお勧めはしない。もし、Vagrantを始めたばかりであるなら、既存のBase Boxの使い方を理解することをおすすめする。

## Base Boxの中身は？

Base Boxの中身は通常、Vagrant用に必要最小限のソフトウェアが機能するように構成されている。 一つの例として、あるLinux Boxは以下のものからのみ構成されている。

* パッケージマネージャ
* SSH
* Vagrantが接続するためのSSHユーザ
* 必須ではないが、場合によってChef、Puppetなど

したがって、プロバイダ毎に追加のソフトウェアが必要となる。例えば、VirtualBox向けのBase Boxを作る場合、共有フォルダが適切に動作するようにVirtulaBox guest addtionsを含むだろう。しかし、AWS Base Boxを作る場合、これは必要ない。

## Base Boxの作成

Base Boxの作成は実際にはプロバイダ特有である。これは、VirutalBox、VMWare、AWSやその他の何を使用しているかに依存し、Base Boxを生成する手順は異なることを意味している。このため、Base Boxの作り方について、この一つの文書で完全な手本を示すことは出来ない。

ここでは、Base Boxを生成するための幾つかの一般的なガイドラインを示すが、Base Boxを生成するためのプロバイダ特有のガイドについてもリンクを示す。

プロバイダ特有のガイド：[VirtualBox Base Boxes](https://www.vagrantup.com/docs/virtualbox/boxes.html)

### PackerとAtlas

成果物をAtlasで自動化するのと同様に、Base Boxとして再配布可能な成果物を生成するには[Packer](https://www.packer.io/)を使用することを強く推奨する。より詳細な情報はAtrasのドキュメント内の[Creating Vagrant Boxes with Packer](https://atlas.hashicorp.com/help/packer/artifacts/creating-vagrant-boxes)を参照のこと。

### ディスク容量

Base Boxを生成する際、面倒な手間なしに楽しく扱える様な十分なディスク容量にするべきである。たとえば、VirtualBoxにおいては、大きめの最大サイズで、動的リサイズドライブを生成するべきである。これは、初期状態においてドライブは実際には小さな領域しか占めないが、必要に応じてディスク領域を最大サイズまで動的に拡張することで、エンド・ユーザに柔軟な環境を与えることができるためである。

AWS Base Boxを生成する場合、ユーザ自身がそれを行えるので、EBSストレージを数テラバイトアロケートすることAMIにを強いてははならない。しかし、それらはユーザの自由であるので、一時的なドライブをマウントすることをデフォルトし、多くのディスク領域を提供する必要がある。

### メモリ

ディスク領域と同様、適正なメモリのデフォルト量のバランスを見出すことは重要である。多くのプロバイダにおいて、デフォルトで過剰な使用が出来ないように、ユーザはVagrantfileによってメモリを変更することができる。もし、Base Boxからの`vagrant up`がすぐに数ギガバイトの多くのメモリを要求した場合、それは、ユーザに貧弱な（そしてややショックな）経験をさせてしまうことになる。Vagrantマシンで楽しむのには十分な、512MBのような値を選択する代わりに、必要に応じて簡単に拡張できる。

### 周辺機器（オーディオ、USBなど）

オーディオやUSBコントローラなどBase Box内のハードウェアに不要なものは無効にする。これらは通常Vagrantの使用上は不必要なものである。多くの場合、Vagrantfileによってあらためて簡単に追加することができる。

## デフォルトユーザの設定

Vagrantのあらゆる事項は変更することができる。しかしながら、VagrantはBase BoxがBoxをひらいて”直ちに動作する”ためのいくつかのデフォルト設定を期待する。Boxを公開配布するためのデフォルトとしてこれらを生成するべきである。

Base Boxを私的に使用するために生成する場合、Boxを開くことで、セキュリティ・リスク(既知のユーザ、パスワード、秘密鍵など）となるので、以降に示す内容に従わないようにすべきである。

### "vagrant"ユーザ

デフォルトでは、VagrantはマシンへSSH接続するユーザとして"vagrant"を期待する。このユーザは、SSHを試みる際のデフォルトとして、非安全な鍵ペアを設定される。また、Vagrantはデフォルトで鍵ベースの認証を使用するが、"vagrant"ユーザに対するパスワードを"vagrant"と設定する慣習がある。必要であれば、ユーザが手動でログインできるようにするためである。

非安全な鍵ペアでSSHアクセスを設定するために、"vagrant"ユーザの公開鍵は`~/.ssh/authorized_keys`ファイルに配置される。OpenSSHはファイル権限に非常に繊細である点に注意すること。そのため、`~/.ssh`は 0700 権限であり、かつ、`authorized_keys`ファイルは 0600 権限であることを確認すること。

Vagrantが起動し、非安全な鍵ペアを検出すると、Boxが稼動している間に、追加の安全策としてランダムに生成された鍵ペアで自動的に置き換えられる。

### ルートパスワード："vagrant"

Vagrantは実際にはどのようなrootパスワードも使用しないし、期待していない。しかしながら、一般的によく知られたrootパスワードによって、一般的なユーザに対して必要に応じてマシンを変更することを容易にしている。

公的に入手できるBase Boxはたいてい、この容易性を継続させるためにrootのパスワードとして"vagrant"を使用している。

### パスワード無しのSudo

これは重要である。Vagrantの多くの点で、デフォルトのSSHユーザがパスワード無しのsudo設定がなされていることを期待している。これは、Vagrantにネットワークの設定や、同期フォルダのマウント、ソフトウェアのインストールをさせるためである。

はじめに、いくつかの最小のオペレーティング・システムのインストールにおいては、デフォルトでsudoすら含まれていない。いくつかの方法でsudoをインストールすることを確認する。

sudoをインストールした後、"vagrant"ユーザ用にパスワード無しのsudoを許すかどうか（通常visudoを使用する）を設定する。これは設定ファイル内の最後にある、以下の行で可能である。

```bash
vagrant ALL=(ALL) NOPASSWD: ALL
```

さらに、VagrantはSSHで接続した際にデフォルトでptyまたはttyを使用しない。`requiretty`の行が設定ファイル内に無いことを確認する必要がある。もし、存在していれば削除すること。これは、sudoがttyを使わずに適切に動作することを許す。この設定を維持しつつ、Vagrantがptyを要求することを設定することができる点に注意すること。しかし、デフォルトではVagrantはこのようにはなっていない。

### SSHの調整

マシンおよびVagrantマシンがインターネットに接続されていない状況下でもSSHの速度を維持するためには、SSHサーバ設定の`UseDNS`設定値を`no`にすること。

これは数秒間かかるSSクライアントへの接続の際のリバースDNSルックアップを回避する。

## Windows用Box

サポートしているWindowsのゲスト・オペレーティング・システムは、Windows 7、Windows 8、Windows Server 2008、Windows Server 2008 R2、Windows Server 2012、Windows Server 2012 R2である。

Windows Server 2003とWindows XPはサポートされていないが、熱心なXPファンであるなら、これは助けになるだろう。

### 基本的なWindowsの設定

* UACを無効にする
* 複雑なパスワードを無効にする
* "Shutdown Tracker"を無効にする
* (non-Coreの場合)ログイン時の"Server Manager"の開始を無効にする

コントロールパネル内でUACを無効化するのに加えて、レジストリからもUACを無効化すべきである。これはWindowsのバージョンごとに異なるが、Windows 8/8.1では以下のコマンドが使用できる。これは、自動化されたPuppetがVagrant Windows Base Boxが動作するためにインストールするように、いくつかのことをできるようにする

```
reg add HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /d 0 /t REG_DWORD /f /reg:64
```

### 基本的なWinRMの設定

WinRMがを有効にして設定するには、WinRMサービスを自動起動に設定し、(あきらかに非安全な）非暗号化のベーシック認証を許可する必要がある。以下のコマンドをWindowsのコマンドプロンプトから実行する。

```
winrm quickconfig -q
winrm set winrm/config/winrs @{MaxMemoryPerShellMB="512"}
winrm set winrm/config @{MaxTimeoutms="1800000"}
winrm set winrm/config/service @{AllowUnencrypted="true"}
winrm set winrm/config/service/auth @{Basic="true"}
sc config WinRM start= auto
```

### WinRM 1.1への追加設定

これらの追加的な設定の手順はWindows Server 2008 (WinRM 1.1)用である。Windows Server 2008 R2、および、Windows 7以降のWIndowsのバージョンではこの部分は無視して構わない。

1. Windows PowerShellがインストールされていることを確認する
2. WinRMのポートを5985に変更するか、WinRM 2.0にアップグレードする

以下のコマンドは、WinRM 1.1のポートをVagrantによって期待されているものに変更する。

```
netsh firewall add portopening TCP 5985 "Port 5985"
winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"}
```

## その他のソフトウェア

この時点で、Vagrantで動作させるBase Boxに絶対に必要なすべての共通ソフトウェアを取り込んだ。しかしながら、要望に応じてインストールできる幾つかの追加的なソフトウエアがある。

将来的には計画しているが、Vagrantはまだ、ChefやPuppetをそれらのプロビジョナを使用する際に自動的にインストールしない。ユーザはshellプロビジョナをこれに使用することができるが、Chef/PuppetをBox外で使用したいのであれば、それらをBase Box内にインストールする必要がある。

インストールについては本書の対象外であるが、非常に簡単である。

これに加えて、このBase Boxのためにデフォルトで欲しいソフトウェアを自由にインストールし、設定すればよい。

## Boxのパッケージ化

BoxファイルにBoxをパッケージ化する方法は、プロバイダ特有である。Base Boxを生成するためのプロバイダ特有の文書を参照して欲しい。幾つかのプロバイダ特有なガイドをこの文書の冒頭にリンクしておいた。

## Boxの配布

Boxは好きな様に配布することができる。しかしながら、バージョン管理、単一のURLで複数プロバイダの配置、アップデートのpush、解析、などを行いたいなら、BoxをHashiCorpのAtlasに追加することを推奨する。

公開・非公開のいずれのBoxについてもこのサービスにアップデートすることができる。

### Boxのテスト

Boxをテストする場合、Vagrantの新しいユーザのふりをして、それを行う。

```bash
$ vagrant box add my-box /path/to/the/new.box
...
$ vagrant init my-box
...
$ vagrant up
...
```

もし、幾つかの異なるプロバイダのためにBoxを作った場合、`--provider`オプションを`vagrant up`の際に指定すること。これが成功すればBoxは動作したということである。

# Boxファイルのフォーマット

これまで、BoxはVirtualBoxからエクスポートされた、ただのtarファイルであった。Vagrantが複数のプロバイダのサポートやバージョン管理のサポートを行っている現在では、Boxファイルはやや複雑なものとなっている。

Vagrant 1.0.x用のBoxファイル(VirtualBoxからエクスポートされたtarファイル)は引き続き、今日のVagrantで動作する。Vagrantがこれらの古いBoxに出会った時、内部で新しいフォーマットに自動的にアップデートする。

今日では異なる2つのコンポーネントがある。

* Boxファイル - これは単一のプロバイダに特化した、または、すべてのプロバイダを含むことができる、圧縮された(tar、tar.gz、zip）ファイルである。Vagrantのコアはこのファイルの中身を使用しない。その代わりに、それをプロバイダに受け渡す。よって、VirtualBoxのBoxファイルはVMwareのBoxファイルなどと異なる中身となっている。
* Boxカタログ・メタデータ - これは(通常HashiCorpのAtlasで相互に交換される)JSON形式のドキュメントであり、それぞれのプロバイダやバージョンに対する、Boxの名前、説明、入手可能なバージョン、入手可能なプロバイダ、実際のBoxファイル(次に示すコンポーネント)へのURLを特定する。このカタログ・メタデータがない場合、Boxファイルは直接追加される事となり、バージョン管理やアップデートのサポートはされない。

それぞれのコンポーネントの対象を次の詳細に示す。

## Boxファイル

実際のBoxファイルはVagrantから必要とされる。Boxファイルと共にメタデータファイルを常に使用することを推奨するが、直接Boxファイルを使用することは、Vagrantにおける遺産を理由としてサポートされる。

Boxファイルはtar、tar.gz、または、zipを使用して圧縮されている。アーカイブの中身はすべてのプロバイダでも単一のプロバイダでも良い。Vagrantコア自身は、後で使用するために展開するのみである。

アーカイブ内で、Vagrantは`metadata.json`というひとつのファイルを期待する。これは上述したカタログ・メタデータ・コンポーネントには無関係なJSONファイルであり、カタログ・メタデータJSON文書が同一Box内に複数のバージョンや、もしかすると複数のプロバイダに関して記述することができるのに対して、(Boxファイル内に)Boxファイル毎に一つの`metadata.json`しか存在しない。

`metadata.json`は少なくともそのBoxのプロバイダ用の"provider"キーを持つ必要がある。VagrantはこれをBoxのプロバイダを確認するために使用する。例えば、VirtualBox用のBoxの場合、`metadata.json`は次のようになる。

```json
{
  "provider": "virtualbox"
}
```

`metadata.json`ファイルがない、または、有効な"provider"キーを少なくとも1つ持っていないJSONであった場合、VagrantはBoxを追加する際に、プロバイダが確認できないためにエラーとする。

その他のキー/値は問題とせずメタデータに追加される。メタデータファイルの値はVagrantに不明瞭な方法で受け渡され、プラグインがそれを使用できるようにする。ここでのポイントは、Vagrantコアはこのファイル内のどんなキーも使用しないということである。

## Boxメタデータ

メタデータは、バージョン管理、アップデート、単一ファイルでの複数プロバイダなどを可能にするための、Boxに対するオプショナル(だが、強く推奨される)なコンポーネントである。

> メタデータは手動で作る必要はない。HashiCorpのAtlasのアカウントを持っていれば、そこにBoxを作ることができ、HashiCorpのAtlasは自動的にメタデータを生成する。フォーマットもここに示されている。

これはJSONドキュメントであり、以下の様な構成となる。

```json
{
  "name": "hashicorp/precise64",
  "description": "This box contains Ubuntu 12.04 LTS 64-bit.",
  "versions": [
    {
      "version": "0.1.0",
      "providers": [
        {
          "name": "virtualbox",
          "url": "http://somewhere.com/precise64_010_virtualbox.box",
          "checksum_type": "sha1",
          "checksum": "foo"
        }
      ]
    }
  ]
}
```

見て分かる通り、JSONドキュメントはBoxの複数のバージョン、複数のプロバイダ、そして異なるバージョンのプロバイダの追加/除去について記述ができる。

このJSONファイルは、ファイルパスを使ったローカルのファイルシステムから、または、URLから`vagrant box add`に直接受け渡され、VagrantはVoxの適切なバージョンをインストールする。複数のプロバイダが入手可能な場合、Vagrantは使用したいプロバイダがどれかを尋ねる。

# 関連記事

* 前の記事：[【Vagrantドキュメント意訳】07.Vagrantfile詳細](http://qiita.com/ringo0321/items/ddf1c8c40014eb88b0b6)
* 次の記事：[【Vagrantドキュメント意訳】09.プロビジョニング](http://qiita.com/ringo0321/items/38743442a9abfc3be5b2)