I have a chef recipe for a multi-node web service, each of which node must get the host name and IP of the other nodes in order to put it in its local configuration.
The code is shown below. The problem is that when assigning node.set [] [] to ruby_block, as shown, the values are empty when a template is created that relies on them. If I want to create this template, I will have to move the entire ruby_block code outside, and it will be “free” in the recipe. This makes unit testing difficult with Chefspec, etc.
Can any chef ask me directly? Is it just impossible to make node.set [] like inside ruby_block? And if so, why doesn't he talk about it in docs?
$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
I also added
subscribes :create, "ruby_block[get host addresses]", :immediately
to the template definition to ensure that ruby_block works before creating the template. It didn’t matter.
source share