このエントリーをはてなブックマークに追加

chef-soloをfabricで実行

chef-soloは簡単なのですが、そのホストで実行する必要があります。いちいち入って実行するのはめんどいですね。

そこでfabricです。fabricはpythonのデプロイツールです。こいつはsshで接続して指定したコマンドを実行してくれます。そして、1.3から並列実行もサポートしています。

fabric

% pip install fabric

でfabricをインストールしておきます。

from fabric.api import *

@parallel
def do_chef_solo():
    sudo("chef-solo -c ~/.chef/solo.rb -j ~/.chef/node.json")

というスクリプトを fabfile.py という名前で保存しておきましょう。

その後、

% fab -H host1,host2,host3 do_chef_solo

と実行すると、host1, host2, host3 で並列にchef-soloが実行されます。なので、待ち時間は1台分です。便利!なお、ホストの指定はコマンドラインではなく env.hosts をfabfile.pyの中で定義することで指定もできます。

ちなみにあまりにもホスト数が多い場合などはデコレータにpool_sizeを指定して一度に実行する数を制限することもできます。より詳細はこちらを見てください。

chef-soloの設定 tips

今まで -j で chef.json を明示的に指定していました。しかし、solo.rbで結構いろいろなことが出来て、chef.jsonを指定する必要は実はありません。

具体的には、solo.rbに以下のように書いておくと、

json_attribs    "/tmp/chef-solo/node.json"
recipe_url      "http://www.example.com/chef-solo.tar.gz"

わざわざ-jでjsonを指定する必要がなくなります。また、recipe_urlを指定してあげると、recipeのtar.gzをhttpで取ってきてくれます。(recipe_urlはコマンドラインオプションでも指定できます)

あるいは、 Ohaiを使うと、platformやhostname, domainなどを展開してくれます。例えば、

require 'rubygems'
require 'ohai'
o = Ohai::System.new
o.all_plugins

file_cache_path "/tmp/chef-solo"
cookbook_path   "/tmp/chef-solo/cookbooks"
role_path       "/tmp/chef-solo/roles"
json_attribs    "/tmp/chef-solo/#{o[:platform]}.json"
recipe_url      "http://www.example.com/chef-solo.tar.gz"

とsolo.rbに書いておくと、 json_attribsにプラットフォームの名前が展開されます。なお、普通のRubyなので、例えば case o[:hostname] でホスト名で読み込むjson_attribsを分ける、ということもできます。

このあたりはここに書いてありました。