Chef Solo+Vagrantで、CentOSにrbenvでRuby環境構築

Chefのお試し。Vagrantで仮想サーバにRuby環境をつくってみる。

## 仮想サーバ起動
Chef社の[Bento](https://github.com/opscode/bento)から、CentOS 6.5のboxを追加。opscode-centos-6.5という名前で。

```
$ vagrant box add opscode-centos-6.5 http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
```

適当なディレクトリに移動して、仮想サーバ起動。

```
$ vagrant init opscode-centos-6.5
$ vagrant up
```

SSHの設定もしておく。vagrant_centosという名前でsshログインできるように。

```
$ vagrant ssh-config --host vagrant_centos >> ~/.ssh/config
```

## knife-soloでchef-soloを実行できるように

knife-soloを使って、Macで作ったクックブックをリモートサーバに転送 & chef-soloを実行できるようにする。

```
$ bundle init
```

```ruby:Gemfile
source "https://rubygems.org"

gem 'knife-solo'
gem 'berkshelf'
```

```
$ bundle
```

gemがいろいろインストールされる。knifeコマンドが利用可能に。
作業ディレクトリで、Mac側にChefリポジトリを新規作成。

```
$ knife solo init .
```

```
Berksfile
data_bags
environments
nodes
roles
site-cookbooks
```

上記のようなファイル・ディレクトリが生成される。
リモートの仮想サーバ（ホスト名: vagrant_centos）にChef Soloをインストールする。

```
$ knife solo bootstrap vagrant_centos
```

準備完了、クックブックを作っていく。

## ruby環境構築のクックブック作成

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

site-cookbooksディレクトリ以下に、ruby-envという名前のクックブック作成。レシピを書いていく。
忘れがちなので、先にNodeオブジェクトの設定ファイルに適用するレシピ名 (=ruby-env)を書いておく。

```json:nodes/vagrant_centos.json
{
  "run_list": [
    "recipe[ruby-env]"
  ]
}
```

### recipes

```rb:site-cookbooks/ruby-env/recipes/default.rb 
%w(gcc openssl-devel readline-devel git).each do |pkg|
  package pkg do
    action :install
  end
end

git "/home/#{node['ruby-env']['user']}/.rbenv" do
  repository node['ruby-env']['rbenv_url']
  reference 'master'
  action :sync
  group node['ruby-env']['group']
  user node['ruby-env']['user']
end

# bash_profileが他のレシピでも変更されている場合は、このやり方だとダメ
template '.bash_profile' do
  source 'bash_profile.erb'
  path "/home/#{node['ruby-env']['user']}/.bash_profile"
  mode '0644'
  owner node['ruby-env']['user']
  group node['ruby-env']['group']
  not_if "grep rbenv /home/#{node['ruby-env']['user']}/.bash_profile"
end

directory "/home/#{node['ruby-env']['user']}/.rbenv/plugins" do
  owner node['ruby-env']['user']
  group node['ruby-env']['group']
  mode '0755'
  action :create
end

%w(ruby-build rbenv-default-gems rbenv-gem-rehash).each do |plgin|
  git "/home/#{node['ruby-env']['user']}/.rbenv/plugins/#{plgin}" do
    repository node['ruby-env']["#{plgin}_url"]
    reference 'master'
    action :sync
    group node['ruby-env']['group']
    user node['ruby-env']['user']
  end
end

template 'default-gems' do
  source 'default-gems.erb'
  path "/home/#{node['ruby-env']['user']}/.rbenv/default-gems"
  mode '0755'
  owner node['ruby-env']['user']
  group node['ruby-env']['group']
  not_if { File.exists?("/home/#{node['ruby-env']['user']}/.rbenv/default-gems") }
end

execute "rbenv install #{node['ruby-env']['version']}" do
  command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv install #{node['ruby-env']['version']}"
  environment 'HOME' => "/home/#{node['ruby-env']['user']}"
  user node['ruby-env']['user']
  group node['ruby-env']['group']
  not_if { File.exists?("/home/#{node['ruby-env']['user']}/.rbenv/versions/#{node['ruby-env']['version']}") }
end

execute "rbenv global #{node['ruby-env']['version']}" do
  command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv global #{node['ruby-env']['version']}"
  environment 'HOME' => "/home/#{node['ruby-env']['user']}"
  user node['ruby-env']['user']
  group node['ruby-env']['group']
  not_if "grep #{node['ruby-env']['version']} /home/#{node['ruby-env']['user']}/.rbenv/version"
end
```

上記レシピでは、Attributeで指定した初期値やテンプレートを利用している。そちらの設定が以下。

### attributes

```rb:site-cookbooks/ruby-env/attributes/default.rb
default['ruby-env']['user'] = 'vagrant'
default['ruby-env']['group'] = 'vagrant'
default['ruby-env']['version'] = '2.1.2'
default['ruby-env']['rbenv_url'] = 'https://github.com/sstephenson/rbenv.git'
default['ruby-env']['ruby-build_url'] = 'https://github.com/sstephenson/ruby-build.git'
default['ruby-env']['rbenv-default-gems_url'] = 'https://github.com/sstephenson/rbenv-default-gems.git'
default['ruby-env']['rbenv-gem-rehash_url'] = 'https://github.com/sstephenson/rbenv-gem-rehash.git'
```

### templates

```erb:site-cookbooks/ruby-env/templates/default/bash_profile.erb
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

```erb:site-cookbooks/ruby-env/templates/default/default-gems.erb
bundler
pry
```

```
$ knife solo cook vagrant_centos
```

Chef Solo実行。
これで、Ruby2.1.2の環境ができる。bundlerやpryといったgemも入った状態。