Vagrant で構築する仮想化技術を使った開発環境


#OS環境を構築する
----

###今回使用している環境
- マシン：Macbook Air(MaxOS X 10.7.4)
- 仮想環境：Virtual Box 4.2.6 r82870
- XCode 4.5.2
 - 事前にCommand Line Toolsはインストールしておく

###RVMのインストール

```
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

source ~/.bash_profile

rvm install 1.9.3
rvm use 1.9.3
rvm --default 1.9.3
```

###.bash_profileの確認

```
PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
source "$HOME/.rvm/scripts/rvm"
```

###Vagrantのインストール

```
gem install vagrant
```

##VeeWeeのインストール
VeeWeeはBoxファイルのテンプレートを生成してくれるパッケージです。

Bundlerが入っているかを確認

```
bundle -v
```

Bundlerが入っていなければ入れる

```
gem install bundler
```

####VeeWeeのダウンロード

```
git clone git://github.com/jedi4ever/veewee.git
```

VeeWeeの.rvmrcを書き換える
1.9.2 となっている部分を 1.9.3 に変更

```.rvmrcの書き換え(veeweeディレクトリの中にある)
vim veewee/.rvmrc
```

####インストール実行

```
cd veewee
bundle install
```

ここの`bundle install`でつまずいたときは`bundle -v`を実行してみて下記のメッセージが出たら対応する

```bundleが正常に認識されているかの確認
$ bundle -v
ERROR: Gem bundler is not installed, run `gem install bundler` first.
```

```対応
rvm reload
```

それでもダメな場合、複数の`bundler`が入っている可能性もあるので、`gem uninstall bundler`を試してみる。
渡しの場合は下記の様に2種類入っていたのでいったん削除。

```複数bundlerが入っているかの確認とアンインストール
$ gem uninstall bundler

Select gem to uninstall:
 1. bundler-1.1.5
 2. bundler-1.2.3
 3. All versions
> 3
Successfully uninstalled bundler-1.1.5

You have requested to uninstall the gem:
	bundler-1.2.3
log4r-1.1.10 depends on [bundler (>= 1.0.0)]
orm_adapter-0.4.0 depends on [bundler (>= 1.0.0)]
paperclip-3.2.0 depends on [bundler (>= 0)]
rails-3.2.8 depends on [bundler (~> 1.0)]
thor-0.16.0 depends on [bundler (~> 1.0)]
uglifier-1.3.0 depends on [bundler (~> 1.0)]
uglifier-1.2.7 depends on [bundler (~> 1.0)]
If you remove this gems, one or more dependencies will not be met.
Continue with Uninstall? [Yn]  y
Remove executables:
	bundle

in addition to the gem? [Yn]  y
Removing bundle
Successfully uninstalled bundler-1.2.3
```

※ ディレクトリを移動するとシェルが認識している状態が変わるようなので、ディレクトリを移動してまたbundlerがうまく認識されていないようであれば`rvm reload`とすると良い。

####再度bundlerをインストール

```bundlerを再認識させる
rvm reload
gem install bundler
```

####仮想マシンの定義

CentOS 6.3 の環境を作成する。

このコマンドはveeweeディレクトリ内で実行する。

```
bundle exec vagrant basebox define centos_64_x86_64 CentOS-6.3-x86_64-minimal
```

そうするとdefinationsにテンプレートが作成されるので、それらを編集する。

####`definition.rb` を編集

ミラーの参照先を変更

```
:iso_file => "CentOS-6.3-x86_64-minimal.iso",
:iso_src => "ftp://ftp.riken.jp/Linux/centos/6.3/isos/x86_64/CentOS-6.3-x86_64-minimal.iso",
```

####`ks.cfg`を編集

これはCentOSインストール用のキックスタート用のファイルで、日本語対応、日本時間対応にする。

```
install
cdrom
lang ja_JP.UTF-8
keyboard us
network --bootproto=dhcp
rootpw --iscrypted $1$damlkd,f$UC/u5pUts5QiU3ow.CSso/
firewall --enabled --service=ssh
authconfig --enableshadow --passalgo=sha512
selinux --disabled
timezone Asia/Tokyo
bootloader --location=mbr
```

####仮想マシンのビルド

```
vagrant basebox build centos_64_x86_64

[centos_64_x86_64] Downloading vbox guest additions iso v 4.2.6 - http://download.virtualbox.org/virtualbox/4.2.6/VBoxGuestAdditions_4.2.6.iso
Fetching file:  62% |oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo                                                                      |  26.5MB 351.8KB/s ETA:   0:00:47
```

しばらく待つ。途中でisoをダウンロードするか聞いてくるのでyesとする。

自動的に仮想マシンが起動するので、またしばらく放置。

プロンプトに

```
[centos_64_x86_64] The box centos_64_x86_64 was build successfully!
[centos_64_x86_64] You can now login to the box with:
[vagrant] ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 7222 -l veewee 127.0.0.1
```
と表示されていれば、このコマンド`ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 7222 -l veewee 127.0.0.1`でveeweeというパスワードでsshログインが可能。

この状態になったら一度落とします。

```
shutdown -h now
```

####boxファイルへエクスポート

構築した仮想環境をboxファイルにエクスポートします。

```
bundle exec veewee vbox export 'centos_64_x86_64'
```
```
$ bundle exec veewee vbox export 'centos_64_x86_64' 
Creating a temporary directory for export
Adding additional files
Creating Vagrantfile
Exporting the box
Executing VBoxManage export centos_64_x86_64 --output /var/folders/0g/thkrchb92p56ypt61cmb2jfh0000gn/T/d20130812-7484-yssofx/box.ovf
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Successfully exported 1 machine(s).
Packaging the box
Cleaning up temporary directory

To import it into vagrant type:
vagrant box add 'centos_64_x86_64' '/Users/nouphet/chefStudy/veewee/centos_64_x86_64.box'

To use it:
vagrant init 'centos_64_x86_64'
vagrant up
vagrant ssh
```

####仮想環境の登録と初期化

エクスポートしたboxを登録します。

```
vagrant box add 'centos_64_x86_64' 'centos_64_x86_64.box'
```

####boxディレクトリの作成
veeweeディレクトリから抜けて、仮想マシン用のディレクトリを作成します。

```boxディレクトリの作成
unalias vagrant
mkdir -p ~/box/centos_64_x86_64
cd ~/box/centos_64_x86_64.box
```

####boxを登録して起動
いよいよ登録して起動します。

```
vagrant box add centos_64_x86_64 ~/box/centos_64_x86_64

vagrant init centos_64_x86_64
```
※ カレントディレクトリにVagrantfileが作成される

```
$ vagrant up
[default] Importing base box 'centos_64_x86_64'...
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
```

ここまで表示されたら起動が完了しているのでsshでログインします。

####ログインする

```
vagrant ssh
Welcome to your Vagrant-built virtual machine.
[vagrant@localhost ~]$
```

ひえー！感動です。 ^^

#開発環境を構築する
----

今回は便利な`Chef-solo`を使って環境の構築を行なってみます。

##Chef-soloを設定
ホスト側のカレントディレクトリ`~/box/centos_64_x86_64`(Vagrantfileのあるディレクトリ)がVirtualBoxの共有フォルダとして/vagrantにマウントされているので、ここで作業します。

```
cd /vagrant/
knife cookbook create myrecipe -o cookbooks
WARNING: No knife configuration file found
** Creating cookbook myrecipe
** Creating README for cookbook: myrecipe
** Creating CHANGELOG for cookbook: myrecipe
** Creating metadata for cookbook: myrecipe
```

途中で`WARNING`が出ますが、knifeコマンドを最初に使っているのでOKです。

これで何もしないcookbookの雛形ができました。
次にVagrantfileの設定をします。
前述の通りVagrantfileは共有フォルダにあるので、ホストOS側で編集しても仮想環境側で編集してもOKです。
(ただしこの時点ではviしか入ってません)。

今回はホストOS側から編集してみます。

```
cd ~/box/centos_64_x86_64
vim Vagrantfile
```

一番下に追記

```Vagrantfile
Vagrant::Config.run do |config|
  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = "cookbooks"
    chef.add_recipe "myrecipe"
  end
end
```

ここでいったん再起動。

```bash
vagrant reload
```

##パッケージをインストール
まずvimをインストールしてみます。
いつもだと `yum install` するのが早いのですが、今回はChef-soloを使って環境を構築するので `cookbooks/myrecipe/recipes/default.rb` に一行追加します。

```cookbooks/myrecipe/recipes/default.rb
package "vim-enhanced"
```

ホストOS側で`vagrant provision`を実行。

```bash
vagrant provision
```

```
vagrant provision
[default] Running provisioner: Vagrant::Provisioners::ChefSolo...
[default] Generating chef JSON and uploading...
[default] Running chef-solo...
[2013-01-02T15:56:22+09:00] INFO: *** Chef 10.16.4 ***
[2013-01-02T15:56:22+09:00] INFO: Setting the run_list to ["recipe[myrecipe]"] from JSON
[2013-01-02T15:56:22+09:00] INFO: Run List is [recipe[myrecipe]]
[2013-01-02T15:56:22+09:00] INFO: Run List expands to [myrecipe]
[2013-01-02T15:56:22+09:00] INFO: Starting Chef Run for localhost
[2013-01-02T15:56:22+09:00] INFO: Running start handlers
[2013-01-02T15:56:22+09:00] INFO: Start handlers complete.
[2013-01-02T15:56:22+09:00] INFO: Processing package[vim-enhanced] action install (myrecipe::default line 9)
[2013-01-02T15:56:47+09:00] INFO: package[vim-enhanced] installing vim-enhanced-7.2.411-1.8.el6 from base repository
[2013-01-02T15:57:03+09:00] INFO: Chef Run complete in 40.950383 seconds
[2013-01-02T15:57:03+09:00] INFO: Running report handlers
[2013-01-02T15:57:03+09:00] INFO: Report handlers complete
```

仮想環境側では何もしていないのに`vim`をインストールすることができました！！

こうやって定義を書いていく事で環境を構築していくことが可能です。
何より、この定義ファイルはホストOS側の共有フォルダに存在しているので、これを元に同じ設定のOSがいくつでも手軽に構築できるという寸法です。

では今度は`httpd``php54``mysql-server`をインストールしてみましょう。

```cookbooks/myrecipe/recipes/default.rb

```