すごい広島 #26 にて、書いている。

すこし前に chef-solo で遊んだので、その時思ったことを書いておく。 自分が考えたことが書いてあるだけなので、不正確な内容も含むかもしれません。

主な参考文献は以下。

「今っぽい Vagrant + Chef Solo チュートリアル」は「入門 Chef Solo」の内容を踏まえた上で、最近の動向も押えてて参考になりました。

目的

chef-solo を試す上で、 一番の目的は「リモートサーバの設定反映をコマンドを一つ実行すれば済むようにしたい」ということでした。

$ knife solo cook ホスト名

このコマンドをローカルマシンで実行すると、「ホスト名」が示すサーバの設定をできるようにしました。

また、「入門 Chef Solo」では、ローカルマシンでテストするにも knife solo を利用していた点が気になっていました。そこは別にしたかったので、vagrant の機能を利用して、

$ vagrant provision

で、済むようにしました。

成果物

GitHub の eiel/cookbook-munin-example に置いています。 使い方も README.md に書いています。

なぜ munin かというと、munin のインストールが必要だったからです。

上記のリポジトリは必要なツールがそろっていれば git clone して vagrant up すれば、chef-solo が走り、設定の終わった仮想マシンが立ち上がります。

Cookbook を修正して、再実行する際には vagrant provision とすれば反映できます。

chef-solo を実行について

chef-solo の実行には、固有情報を記述した「JSONファイル」が必要になります。 「JSONファイル」はエントリーポイントのような位置づけで、実行するレシピの記述ができます。 Cookbook は汎用的なライブラリのようなもので、プログラミングに例えると「引数を与える必要があったり、呼び出すメソッドを指定する」必要があり、そういった指定するためのものが、「JSONファイル」になります。 設定ファイルとも言えます。

Cookbook について

以下は Chef 使ってみた結果で構築された個人のイメージを記述します。

Chef を Ruby におきかえると Cookbook に相当するのが gem です。 Rubygems ではなく、ひとつの gem です。

Chef を試すときに最初に作成する Cookbooks (複数形のほう) は gem を保存しておく場所と考えると良いと思いました。 Chef を使う場合は、トップレベルのスクリプトを書くところがなく、いきなりディレクトリ構造の整理した場所にコードを書かされます。

別の誰かが書いた Cookbook を使う場合は、「JSONファイル」の run_list にレシピを指定するだけで chef を利用できるわけです。 Cookbook はいろんなレシピをまとめていて、Chef を Ruby に置き換えると「レシピはクラスのようなもの」です。 gem 添付されているクラスを使うかどうかは、コードを書くときに決めることです。 chef だと run_list にかくことで使われます。

つまり Cookbook を書くというのは、いきなり gem を作るような感じになります。
なるほど、これは難しい。

knife solo について

knife solochef solo を外部サーバで実行するためのツールです。

chef solo を実行するには、設定したいサーバにログインして、利用する Cookbook をダウンロードして、jsonファイルを用意します。 これはめんどくさいので、リモートサーバを指定して、用意している Cookbook をアップロードして、リモートサーバで chef solo を実行します。

なぜ knife solo でテストの実行をしたくないか

Vagrant にIPアドレスを設定する必要があり、「JSONファイル」をコミットしなければならなかったからです。 IPアドレス.json ファイルをgitリポジトリにコミットするのが嫌でした。

vagrant の box に chef がインストールしなければいけない問題は vagrant-omnibus プラグインで解決しました。 このプラグインは vagrant up した際に、chef がインストールされていない場合にインストールしてくれます。

provider

レシピで使える命令を追加できる Chef の機能です。 名前空間が Cookbook ごとに閉じているようで、利用したいクックブックの metadata.rb に記述しておかなければ、追加命令が使えません。 ちなみに、事前にそのクックブックのレシピを実行していれば、利用できました。はまる原因になりそうなので、metadata.rbには、ちゃんと書いたほうが良いと思います。

vagrant ssh

vagrant ssh には -- につづいて ssh の引数を追加できます。

vagrant にホストオンリーアクセスできるように指定してないので、とりあえず、これを利用してサーバのサービスにアクセスしてます。

$ vagrant ssh -- -L 4000:localhost:80

としておけば、 https://localhost:4000/ で、Webサーバにアクセスできます。 若干めんどくさい…。

vgrant provision

vgrant provision で使う「JSONファイル」は用意する必要がなく、Vagrantfile に同等の記述を行います。

以下の風に書いている。

config.vm.provision :chef_solo do |chef|
  chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
  chef.add_recipe "munin"
end

knife-solo をベースしたリポジトリになっているので site-cookbooks を追加しています。 ひとつの cookbook を書くためのリボジトリであれば、不必要でしょう。

site-cookbooks にあるファイルを汎用化してきたら、個別のリポジトリをつくると良さそうです。

その他

Databags や Attributes, librarian-chef も試したけど記憶からすでにない…。 serverspec はまだ試せてない。