VagrantでChef Soloのバージョンを指定する方法


## あらまし

VagrantでChef soloを使っているとエラーが出た。

```
ERROR: undefined method `sensitive' for Chef::Resource::Template
```

[ここ](http://blog.yucchiy.com/2014/10/28/chef-solo-mysql/)を見るとどうもChef soloのバージョンが古いようなのでアップデートしようとしたのでその手順をまとめてみた。

## 流れ

まずエラーの確認。

```
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: Forking chef instance to converge...
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] DEBUG: Forked instance now converging
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: *** Chef 11.8.2 ***
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] INFO: Chef-client pid: 1921
==> rqbbitmq1: [2014-12-26T06:11:38+00:00] DEBUG: Building node object for rabbitmq1

...

[2014-12-26T06:11:39+00:00] ERROR: undefined method `sensitive' for Chef::Resource::Template
```

`sensitive`というメソッドがないというのが原因と言われるが、[Chefのドキュメント](https://docs.chef.io/resource_common.html)には載っている。

同じエラーでぐぐってみると以下の記事が見つかった。

[ChefのMySQLクックブックでNoMethodError: Undefined Method `sensitive' for Chef::Resource::Executeの対処](http://blog.yucchiy.com/2014/10/28/chef-solo-mysql/)

そこではChefのsoloのバージョンが古いので上げれば動くようになると書いてあったが、Vagrantでchef soloのバージョンを上げる方法がわからないので調べる。

[Vagrantのchef soloについてのドキュメント](https://docs.vagrantup.com/v2/provisioning/chef_solo.html)を見ると`version`指定でいける模様。

```ruby:Vagrantfile
conf.vm.provision :chef_solo do |chef|
  chef.log_level      = :debug
  chef.json           = load_node_json(conf.vm.hostname)
  chef.cookbooks_path = %w(../ berks-cookbooks)
  chef.version = '11.16.4'
end
```

実行

```
VagrantPlugins::Chef::Config::ChefSolo
Bringing machine 'rqbbitmq1' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

chef solo provisioner:
* The following settings shouldn't exist: version
* The following settings shouldn't exist: version
```

なんか`version`がないと怒られた。
ドキュメントを読み直すと`install`オプションに`force`を指定しないといけない模様なので指定してみる。

```ruby:Vagrantfile
conf.vm.provision :chef_solo do |chef|
  chef.log_level      = :debug
  chef.json           = load_node_json(conf.vm.hostname)
  chef.cookbooks_path = %w(../ berks-cookbooks)
  chef.install = 'force'
  chef.version = '11.16.4'
end
```

再度実行

```
Bringing machine 'rqbbitmq1' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:

chef solo provisioner:
* The following settings shouldn't exist: install, version
* The following settings shouldn't exist: install, version
```

おかしい・・・動かない・・・
しかたがないのでソースコードを覗くためにGithubのVagrantを見に行く。

どうやら[このコミット](https://github.com/mitchellh/vagrant/commit/a8fa4bccc745ff9b86f130cf33576335f8f56f52)でversionとinstallが使えるようになったらしい。

versionは1.7.0からということで自分の手元を確認。

```
% vagrant -v
Vagrant 1.6.5
```

1.7以前だったのでバージョンアップ

```
% vagrant -v
Vagrant 1.7.1
```

これで上記の`chef.install='force'`と`chef.version='11.16.4'`を指定したVagrantfileで再度実行

```
   rqbbitmq1: Installing Chef (11.16.4)...
```

無事に動いた。

## 結論

* Vagrantのバージョンが1.7以降であればChef Soloのバージョンを指定してインストールが出来る
* バージョンを指定したインストールをするために
 * Vagrantfileのprovisionでchef_soloを指定する
 * chef_soloの設定で`install='force'`と`version='任意'`を指定する


## 参考
* [ChefのMySQLクックブックでNoMethodError: Undefined Method `sensitive' for Chef::Resource::Executeの対処](http://blog.yucchiy.com/2014/10/28/chef-solo-mysql/)
* https://docs.chef.io/resource_common.html
* https://docs.vagrantup.com/v2/provisioning/chef_solo.html
* https://github.com/mitchellh/vagrant/commit/a8fa4bccc745ff9b86f130cf33576335f8f56f52