Itamaeが構成管理を仕込みます! ~新進気鋭の国産・構成管理ツール~

第3回 ノード属性で汎用的なレシピを書く

この記事を読むのに必要な時間:およそ 3.5 分

前々回前回でItamaeの基本的な使い方とレシピの書き方を解説しました。今回はノード属性の使い方について解説します。

ノード属性(node attributes)

Itamaeのレシピはできるだけ汎用的にし,様々なホストで利用できる形にするのが理想です。汎用的になっていることで再利用性が高まりますし,プラグインとして公開することもできます。

レシピを汎用的なものにするためには,レシピ自体に設定値などをハードコードせず,ホスト固有の情報などを実行時に注入できる必要があります。このようにレシピやテンプレートから実行時に設定した値を参照できる仕組みとしてノード属性(node attributes)があります。

Itamaeの実行時のオプションに--node-jsonを渡すと,JSONの内容がノード属性として設定され,その値がレシピ内から参照できるようになります。

templates/etc/nginx/nginx.conf.erb:

$ cat node.json
{
  "nginx": {
    "version": "1.9.3-1+trusty0"
  }
}
$ itamae local --node-json node.json recipe.rb

--node-jsonでJSONを指定した場合,レシピ内ではnodeを使って参照できます。

package "nginx" do
  version node['nginx']['version']
  # また,node[:nginx][:version] や node.nginx.version でも参照できる
end

このようにJSONでnginxのバージョンを指定できるようにしておくと,ホストやロールごとにバージョンを変更することができ,柔軟にプロビジョニングを行えるようになります。

また,JSONの代わりにYAMLを指定することもできます。

$ cat node.yaml
nginx:
  version: "1.9.3-1+trusty0"
$ itamae local --node-yaml node.yaml recipe.rb

テンプレートからの利用

nodeはレシピだけではなくテンプレート内からも参照することができます。テンプレートの使い方については前回の記事を参照してください。設定ファイルを動的に生成する場合に有用です。

recipe.rb:

node.reverse_merge!({
  'nginx' => {
    'worker_processes' => 'auto',
  }
})

template "/etc/nginx/nginx.conf" do
  owner 'root'
  group 'root'
  mode  '644'
end

templates/etc/nginx/nginx.conf.erb:

worker_processes <%= node['nginx']['worker_processes'] %>;

(後略)

このようなレシピを書いておくと,ホストごとにworker_processesを設定できます。

デフォルト値の指定

package "nginx" do
  version node['nginx']['version']
end

このようなレシピをJSONを指定せず実行すると,値が見つからずエラーになってしまいます。値が設定されなかった場合にデフォルト値を利用するように設定することでこれを防げます。

デフォルト値を設定するにはreverse_merge!メソッドを利用します。reverse_merge!は値が設定されていない場合のみ値を設定するメソッドです。

# nodeが以下のようになっていて
# {
#   "nginx" => {
#     "worker_processes" => 1
#   }
# }

# reverse_merge!を呼ぶと
node.reverse_merge!({
  'nginx' => {
    'version' => '1.9.3-1+trusty0'
  }
})

# nodeはこのようになります
# {
#   "nginx" => {
#     "worker_processes" => 1,
#     "version" => "1.9.3-1+trusty0"
#   }
# }

このメソッドを利用するとJSONで値が設定された場合にはその値を使って,設定されていない場合はデフォルト値を使うレシピを書けます。

# recipe.rb

node.reverse_merge!({
  'nginx' => {
    'version' => '1.9.3-1+trusty0'
  }
})
package "nginx" do
  version node['nginx']['version']
end

この場合,大部分のホストでは1.9.3-1+trusty0を利用して,特定のホストやロールでは他のバージョンを利用する,といったことが可能になります。また,reverse_merge!を使ってロールごとにデフォルト値を変更することもできます。例えば,appサーバとproxyサーバでnginxのプロセス数を変更したい場合,以下のように記述できます。

# recipes/nginx.rb
node.reverse_merge!({
  'nginx' => {
    'worker_processes' => 'auto',
  }
})

template '/etc/nginx/nginx.conf'
# roles/app.rb
node.reverse_merge!({
  'nginx' => {
    'worker_processes' => 1,
  }
})

# この時点でnginx.worker_processesが設定されるため,recipes/ruby.rbの設定は使われない

include_recipe '../recipes/nginx.rb'
# roles/proxy.rb
# この時点でnginx.worker_processesは設定されていないため,recipes/ruby.rbの設定が使われる

include_recipe '../recipes/nginx.rb'

appロールでは1プロセス,proxyロールではauto(nginxレシピのデフォルト値)が使われ,更に上書きしたい場合は--node-json--node-yamlを指定することができます。

著者プロフィール

荒井良太(あらいりょうた)

クックパッド株式会社 インフラエンジニア。ソフトウェアでのインフラの改善,運用の自動化に興味があり,オペレーションのない世界を夢見ている。休日はOSS活動をしていることが多い。ItamaeInfratasterの開発者。

URL:http://ryotarai.info

コメント

コメントの記入