マルチノード Web サービスの Chef レシピがあります。各ノードは、他のノードのホスト名と IP を取得して、それを独自のローカル構成に配置する必要があります。
コードを以下に示します。問題は、node.set[][] 割り当てが示されているように ruby_block で行われると、それらに依存するテンプレートが作成されるときに値が空になることです。そのテンプレートを作成したい場合は、ruby_block のコードをすべて外部に移動し、レシピで "loose" する必要があります。これにより、Chefspec などで単体テストを行うことが難しくなります。
シェフの第一人者は私を正すことができますか? ruby_block 内でこのように node.set[] を実行することは単に不可能ですか? もしそうなら、なぜドキュメントでそう言わないのですか?
$cm = { :name => "web", :hostname => "" , :ip_addr => "" }
$ca = { :name => "data", :hostname => "" , :ip_addr => "" }
$cg = { :name => "gateway", :hostname => "" , :ip_addr => "" }
$component_list = [$cm, $ca, $cg]
ruby_block "get host addresses" do
block do
for cmpnt in $component_list
# do REST calls to external service to get cmpnt.hostname, ip_addr
# .......
node.set[cmpnt.name]['name'] = cmpnt.name
node.set[cmpnt.name]['host'] = cmpnt.hostname
node.set[cmpnt.name]['ip'] = cmpnt.ip_addr
end
end
end
template "/etc/app/configuration/config.xml" do
source "config.xml.erb"
variables( :dataHost => node['data']['host'],
:webHost => node['web']['host'],
:gatewayHost => node['gateway']['host'] )
action :create
end
私も追加しました
subscribes :create, "ruby_block[get host addresses]", :immediately
テンプレート定義に追加して、テンプレートが作成される前に ruby_block が実行されるようにします。これは違いはありませんでした。