chef-soloで環境設定¶
chefはサーバ構成管理ツールです。構成を設定ファイルとして書き残しておき、 chefを実行すればそのとおりにサーバを構築してくれます。また、何度実行し ても同じように構築してくれますし、サーバ構成をいじったとしても修正して くれます。
というわけで、chefを使ってみたのでそのメモ。
事前準備¶
chefはrubyで作られていますので、rubyが必要です。また、chef自体のインス トールにはgemが楽ちんです。
% gem install chef
chefにはサーバなどがありますが、今回は単独で実行できる chef-solo のみ を使います。
雛形作成¶
後述するcookbookなどの雛形を作ってくれるRakefileがopscodeのサイトにあ ります。
githubのopscodeから取ってきます。
% git clone git://github.com/opscode/chef-repo.git
この構成をそのまま使うのが吉です。また、ここにあるRakefileを使うことで、 cookbookの雛形作成も楽に出来ます。
cookbook¶
cookbookとはRecipeなどの設定ファイルをひとまとめにしたディレクトリ。そ の中身はcookbookは以下のディレクトリで構成されます。
attributes
definitions
files
metadata.rb
providers
recipes
resources
templates
これらは上記Rakefileを使えば、
% rake new_cookbook COOKBOOK=test
と打つだけで雛形を作ってくれます。
recipe¶
レシピです。このレシピに書いてあるとおりにサーバが設定されます。
例えば、ディレクトリを作ってリンクを張る、という設定はこんな感じです。
directory "/tmp/tmpdir" do
mode "0755"
action :create
end
link "/tmp/link" do
to "/tmp/tmpdir"
end
ここで、"directory"と"link"をResourceと呼びます。Resourceは順番に意味が ありますので、directory -> link の順番で呼ばれます。
Resourceにはいろいろあって、例えば、remote-fileというResourceはsourceで 指定した、cookbook/files以下にあるファイルを指定の場所にコピーします。 ディレクトリまるごとの場合はremote-directoryを使います。
remote_directory "/tmp/dir" do
source "tmpdir"
owner "apache"
group "apache"
mode "0755"
end
また、templateというresourceを使うと、cookbook/template以下にある、erb で書いたテンプレートファイルに値を埋めてファイルを作成してくれます。
詳しくは Resourceの説明 を見てください。
これらのResourceは「何度繰り返しても同じ結果になります」大事です。英語 で言うと、idempotentです。冪等性(べきとうせい)とも言います。
shell scriptでmkdir hogeと二回打つと、二回目は「File exists」というエラー になりますよね?(-p使えという話もありますが)しかし、chefを使った場合で はエラーになりません。これはchefが自動的に判断して実行しないからです。
また、templateであれば、もし手動でなにかを書き換えていた場合にはその変 更は書き潰されますし、ownerを変更した場合はchefのレシピ通りに戻されます。
script Resource¶
script Resourceはbash、ruby、Pythonなどのスクリプトを実行出来ます。強力 な反面、idempotentではなくなる場合もあるため、使用には注意が必要です。 できるだけ使わない方がいいでしょう。
とはいえ、make installが必要な場合等はあるんですけどね。
Action¶
httpd.confを書き換えたらhttpdをreloadする、などのように、「この Resourceを実行したらこのResourceを実行する」などはnotifiesを使います。
このあたりは Rubyマガジン Chef でサーバ管理を楽チンにしよう! (第 2回) を参考にしてみて ください。
chef-soloの実行¶
最低限CookbookとRecipeがあればchef-soloは実行できます。以下の二つのファ イルを作成しましょう。defaultではsolo.rbは /etc/chef/solo.rb を見に行く ようです。
- chef.json
chef-soloを実行するターゲットの設定ファイル
- solo.rb
cookbookのパスなどを設定
{
"run_list": [
"recipe[test]",
"recipe[test::test2]"
]
}
run_list内のrecipeは複数書けます。ここで[test::test2]とあるのは、
test/
recipes/
default.rb
test2.rb
のtest2.rbを実行しますということです。solo.rbはこう書きます。
file_cache_path "/tmp/chef-solo"
cookbook_path ["/path/to/cookbooks", "/path/to/cookbooks2"]
role_path "/path/to/roles"
log_level :debug
主にパス設定ですね。cookbook_pathは複数設定出来ます。role_pathは複数設 定出来ません。
さて、この二つのファイルを用意しておけばあとは以下のコマンドを打つだけです。
% sudo chef-solo -c /path/to/solo.rb -j /path/to/chef.json
log_levelをdebugにしているのでかなり多くの情報がずらずらーっと出てくる と思います。
attributes¶
ここまでで一通りできるのですが、もう一つattributesを覚えておくと今後便利です。
attributesとは、recipeやテンプレートで使える変数を外出ししたものです。
例えば、 cookbook/attributes/default.rb にこう書きます。
default["apache"]["version"] = "2.2.22"
default["apache"]["conf_dir"] = "/usr/local/apache/conf/"
こう書いておくと、Recipeでたとえばこう書けます。
template "#{node.apache.conf_dir}/httpd.conf" do
source "httpd.conf"
owner "apache"
group "apache"
mode "0644"
end
また、テンプレートの中で
ServerRoot "/usr/local/apache-<%= node.apache.version %>"
と書けます。
このattributesはjsonの中で上書きできます。
"override_attributes": {
"apache": {"version": "2.4.2", "conf_dir": "/etc/apache/conf/"}
},
このように変数をレシピの外に出しておくことで、レシピを変えることなく環 境に合わせた設定ができます。
definitions¶
definitionは自分で新しいResourceを作れる仕組みです。definitionを使うことで、 何度も同じResourceを定義する必要がなくなります。
definitionは cookbook/definitionsの下に、例えば postgresql_func.rb とい う名前で作ります。
define :postgresql_func, :action => :create, :owner => "postgres" do
# 名前がpostgresql_func、デフォルトの設定が残り
contrib = node.postgresql.contrib_dir
# node.postgresql.contrib_dirはattributesで設定
case params[:action]
when :create
execute "psql -1 -f #{contrib}/#{params[:mod]}.sql #{params[:name]}" do
# params[:name] はpostgres_funcの引数
user "postgres"
not_if "psql -At1 -c \"SELECT prosrc FROM pg_proc \" #{params[:name]} | grep '#{params[:func]}'", :user => "postgres"
end
when :drop
execute "psql -1 -f #{contrib}/uninstall_#{params[:mod]}.sql
#{params[:name]}" do
user "postgres"
not_if "psql -At1 -c \"SELECT prosrc FROM pg_proc \" #{params[:name]} | grep '#{params[:func]}'", :user => "postgres"
end
end
end
こうしておけば、あとはrecipeの中でこう使えます。
postgresql_func "template1" do
mod "dblink"
func "dblink_connect"
end
postgresql_funcの引数(ここでは"template1")が params[:name] として渡さ れます。
なお、definition自体はその中で包含するResourceで置き換えられます。つま り、実際にはdefinitionというResourceは作られません。そのため、 definitionに対してActionを送ることは出来ません。もしResourceに対して Actionを送りたければ Provider を使うとのことです。
role¶
roleはattributeの設定やrun_listの設定をまとめたものです。使うには以下の ように solo.rb にrole_pathを加えておきます。(cookbook_pathとは違い、複 数指定できません)
file_cache_path "/var/chef-solo"
cookbook_path "/var/chef-solo/cookbooks"
role_path "/var/chef-solo/roles"
で、実際のroleはこんな感じ。
/var/chef-solo/roles/test.json
{
"name": "test",
"default_attributes": { },
"override_attributes": { },
"json_class": "Chef::Role",
"description": "This is just a test role, no big deal.",
"chef_type": "role",
"run_list": [ "recipe[test]" , "recipe[test2]"]
}
こういうファイルを作っておけば、あとは chef.json は
{ "run_list": "role[test]" }
と書くだけで、test roleが適用されます。attributeなんかもroleの中に書い ておけるので、依存性が低くなります。
Comments
comments powered by Disqus