Berkshelf 3(beta)でcookbookを作成し、Vagrantで試す

## Berkshelf 3 のインストール

Ruby(+RubyGems), [VirtualBox](https://www.virtualbox.org/), [Vagrant](http://www.vagrantup.com/)はインストール済みとします。

Berkshelfは ver.2 が開発終了しているようなので、新しい ver.3 の開発版で試します。

```
$ gem install berkshelf --pre
```

## Cookbookの作成

適当なディレクトリにクックブックのひな形を作成

```
$ berks cookbook sample-webapp
$ cd sample-webapp
```

**注意** このディレクトリ中にある `Berksfile` は基本的に変更しません。依存性は `metadata.rb` に記述します。

```
$ vim metadata.rb
````

作成するクックブックに必要な依存パッケージを追加。

```metadata.rb
depends "tomcat"
```

`recipes/default.rb` に tomcat のインストールを追加。

```recipe/default.rb
include_recipe "tomcat"
```

`attributes/default.rb` に tomcat のインストール設定値を追記。

```attributes/default.rb
# Java 7
normal['java']['jdk_version'] = 7

# Tomcat 7 : 本来は base_version を変更したら全て変わるように修正されるべきなんだけど
normal['tomcat']['base_version'] = 7
normal['tomcat']['user'] = "tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['group'] = "tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['home'] = "/usr/share/tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['base'] = "/var/lib/tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['config_dir'] = "/etc/tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['log_dir'] = "/var/log/tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['tmp_dir'] = "/tmp/tomcat#{node["tomcat"]["base_version"]}-tmp"
normal['tomcat']['work_dir'] = "/var/cache/tomcat#{node["tomcat"]["base_version"]}"
normal['tomcat']['context_dir'] = "#{node["tomcat"]["config_dir"]}/Catalina/localhost"
normal['tomcat']['webapp_dir'] = "/var/lib/tomcat#{node["tomcat"]["base_version"]}/webapps"
normal['tomcat']['keytool'] = 'keytool'
normal['tomcat']['lib_dir'] = "#{node["tomcat"]["home"]}/lib"
normal['tomcat']['endorsed_dir'] = "#{node["tomcat"]["lib_dir"]}/endorsed"
```

## cookbooksの保存

`vagrant` は実行する際に `cookbooks` にあるクックブックを参照するので、 Berkshelfで一箇所にまとめます。

```
$ berks vendor cookbooks
```

このとき、 `Berksfile.lock` が作成され通常は`berks`コマンドで依存リストの変更ができなくなるので、
`metadata.rb` の依存性に変更がある場合は以下のようにします。

```
$ rm -rf Berksfile.lock cookbooks/
$ berks vendor cookbooks
```

## Vagrantの実行

Vagrant実行時にChef-clientを自動的に挿入したい場合は vagrant-omnibus プラグインを使います。

```
$ vagrant plugin install vagrant-omnibus
```

また、現時点では vagrant-berkshelf プラグインは使えません。（開発終了するようです）

以下、Vagrantfileからの抜粋です。他にネットワーク設定などがデフォルトで指定されていると思います。
必要があれば変更します。

```ruby:Vagrantfile
Vagrant.require_plugin "vagrant-omnibus"

Vagrant.configure("2") do |config|

  config.vm.hostname = "spiralg-webapp-berkshelf"
  
  # Chefのバージョン指定  
  config.omnibus.chef_version = :latest

  # box の指定
  config.vm.box = "debian-7.2-amd64"
  config.vm.box_url = "https://dl.dropboxusercontent.com/u/197673519/debian-7.2.0.box"

  config.vm.provision :chef_solo do |chef|
    chef.run_list = [
      "recipe[sample-webapp::default]"
    ]
  end
end
```

`vagrant up` でVMの起動とプロビジョニング（chef-soloで環境構築）が実行されます。

```
$ vagrant up
```

## レシピなどを書きなおすとき

なんやかんやで recipes/, attributes/ などのソースコードを変更しながら開発しますが、 `vagrant provision` などでは反映されません。
これは `berks vendor cookbooks` の時にコピーされたcookbookを参照しているからです。

Vagrantへ反映するには cookbooks を更新する必要がありますが、現時点では `berks vendor` コマンドでは上書きが出来ないため、一旦削除する必要があります。

先に書いた更新手順と同じですが、cookbooksの更新を行うスクリプトを作ってもいいと思います。

```update_cookbooks.sh
rm -rf Berksfile.lock cookbooks/
berks vendor cookbooks
```

## 追記：test-kitchenを使いましょう

`cookbooks` を削除して `berks cookbook` で作りなおして…という手順ではなく、ちゃんとやるなら `test-kitchen` を使いましょう、という話でした。

[詳しくはこちら](http://qiita.com/sawanoboly/items/9f560bd63ad0712b17ba)