Vagrant で作成した仮想マシンに chef-solo を使用して Rails 環境を構築

# Vagrant (Ubuntu) に chef-solo を使用して Rails 環境の構築を実施
* git, rbenv, ruby, rails をインストールするための chef の recipe を作成する
* vagrant を使用して新規に仮想環境を作成
* chef-solo を使用して作成した仮想環境に rails をインストールする

# できていないこと(要改善)
* chef を使用していながら bash コマンドを多用しているため、冪等性が保証できていない

# 前提条件
* chef を使うために操作するマシン(workstation) に Mac を、環境を設定する対象のマシン(node) を Vagrand で作成する Ubuntu server 12.04 とする

* VirtualBox, Vagrant, chef, knife-solo が Mac にインストールされていること
    * vagrant や chef の導入については別の投稿にまとめています
        * [Vagrant を使用して仮想マシンを作成してみる](http://qiita.com/kasaharu/items/5270f6d9737e7bd9b917)
        * [初めての Chef](http://qiita.com/kasaharu/items/395b55c06f8b4477019d)


# 設定
## vagrant
* Vagrant の公式ページで公開している precise32 の box を取得

```bash
$ vagrant box add precise32 http://files.vagrantup.com/precise32.box
```

* インストールをすると ~/.vagrant.d/boxes/precise32 ができる
* 今回はホームディレクトリ下に Vagrant/CreateRailsEnvOnUbuntu/ を作成し、作業用ディレクトリとする
* 設定ファイルの生成

```bash
$ vagrant init precise32
```

* 実行後に Vagrantfile ができているいることを確認
* Vagrantfile をエディタで開き、 ``` config.vm.network :private_network, ip: "192.168.33.10"``` のコメントアウトを外し保存
* 起動

```bash
$ vagrant up
```

* ログイン

```bash
$ vagrant ssh
```

* ``` $ ifconfig``` で eth1 に 192.168.33.10 がふられていることを確認
* ログイン設定を保存
    * ```$ exit``` で一度終了
    * 下記コマンドで設定を保存しておく
    * ```$ vagrant ssh-config --host “任意の名前” >> ~/.ssh/config```
    * $ ssh “任意の名前” で先ほどの仮想環境にログイン出来るようになる(今回は ubuntu0321 とする)


## Chef
* chef のリポジトリポジトリを作成する

```bash
$ knife solo init railsenv
```

* 作成したリポジトリに移動

```bash
$ cd railsenv
```

* chef solo を使用し、node (ubuntu 側) に Chef をインストール

```bash
$ knife solo prepare ubuntu0321
```

* 下記が出力されるとインストール完了

> Thank you for installing Chef!

* 同時に railsenv/nodes/ubuntu0321.json が作成される

# Recipe の準備
## git のインストール
* まずは、git を導入
* railsenv/ ディレクトリで下記コマンドを入力

```bash
$ knife cookbook create git -o site-cookbooks
```

* site-cookbooks/git/ というディレクトリが出来る
* site-cookbooks/git/recipes/default.rb を編集する

```rb:default.rb
%w{libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev}.each do |pkg|
  package pkg do
    action :install
  end
end

package "git-core" do
  action :install
end
```

* package コマンドの install アクションで指定したパッケージをインストールできる

* nodes/ubuntu0321.json を編集する

```json:ubuntu0321.json
{
  "run_list":[
    "recipe[git]"
    ]
}
```

* git/recipes/ 下のファイルを実行できるようにする

* 下記コマンドで chef を実行

```bash
$ knife solo cook ubuntu0321
```

## ruby, rails のインストール

* railsenv/ ディレクトリ ruby 用の cookbook を作成する

```bash
$ knife cookbook create ruby -o site-cookbooks
```

* site-cookbooks/ruby/recipes/default.rb を編集する

```rb:default.rb
# package コマンドでインストール
%w{build-essential curl zlib1g-dev libreadline-dev libyaml-dev libxml2-dev libxslt-dev sqlite3 libsqlite3-dev nodejs make gcc ncurses-dev libgdbm-dev libdb4.8-dev libffi-dev tk-dev}.each do |pkg|
  package pkg do
    action :install
  end
end

# git コマンド
# action sync は初回時は clone, 存在していたら pull をする
git "/home/vagrant/.rbenv" do
  repository "git://github.com/sstephenson/rbenv.git"
  reference "master"
  action :sync
  user "vagrant"
  group "vagrant"
end

# directory コマンドでディレクトリ作成
%w{/home/vagrant/.rbenv/plugins}.each do |dir|
  directory dir do
    action :create
    user "vagrant"
    group "vagrant"
  end
end

git "/home/vagrant/.rbenv/plugins/ruby-build" do
  repository "git://github.com/sstephenson/ruby-build.git"
  reference "master"
  action :sync
  user "vagrant"
  group "vagrant"
end

# bash コマンドが使えるが複数回繰り返すと冪等性が保証されない
# 処理の中で、source ~/.bashrc をしているが再読込されないため
# 以降の処理を実行するには、一度 vagrant から出て、再度 ssh ログインする必要がある
bash "insert_line_rbenvpath" do
  environment "HOME" => '/home/vagrant'
  code <<-EOS
    echo 'export PATH="/home/vagrant/.rbenv/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(rbenv init -)"' >> ~/.bashrc
    chmod 777 ~/.bashrc
    source ~/.bashrc
  EOS
end


bash "install ruby" do
  user "vagrant"
  group "vagrant"
  environment "HOME" => '/home/vagrant'
  code <<-EOS
    /home/vagrant/.rbenv/bin/rbenv install 2.0.0-p0
    /home/vagrant/.rbenv/bin/rbenv rehash
    /home/vagrant/.rbenv/bin/rbenv global 2.0.0-p0
  EOS
end

bash "install rails" do
  code <<-EOC
    export PATH="/home/vagrant/.rbenv/bin:$PATH"
    eval "$(rbenv init -)"
    gem update --system
    gem install --no-ri --no-rdoc rails
  EOC
end
```

# 参考
* 入門 ChefSolo
* [Ubuntu に rbenv + Bundler で Rails 4 をインストールする](http://www.d-wood.com/blog/2013/09/25_4699.html)
* [Chefでrbenvを使ってRubyをインストールする](http://tanimichi.com/blog/157)