Chef each loop for each loop
Solution 1
How I would tackle the problem:
In attributes/default.rb
:
default['services']['service1']['port'] = 11001
default['services']['service2']['port'] = 11002
default['services']['service3']['port'] = 11003
OR (alternative syntax):
default['services'] = {
"service1" => { "port" => 11001 },
"service2" => { "port" => 11002 },
"service3" => { "port" => 11003 }
}
In the recipes/default.rb
:
node['services'].each do |serv,properties|
template "/etc/services/conf.d/service-#{serv}.conf" do
source "service-#{serv}.conf.erb"
owner 'serviceaccount'
group 'serviceaccount'
mode '0644'
variables(
:service => serv,
:ports => properties['port']
)
end
end
When iterating over a hash (what node attributes are based on) you can use the |key,values|
syntax of ruby to get the key in the first variable and the value (which could be another hash) in the second variable.
Solution 2
I would instead use a hash with the keys as your service names and values as your port numbers. Then you can increment through your hash with the key and the value.
Using your example code, something like:
services = { 'service1' => 11001, 'service2' => 11002, 'service3' => 11003 }
And then in your recipe:
node['recipe']['services'].each do |serv, port|
template "/etc/services/conf.d/service-#{serv}.conf" do
source "service-#{serv}.conf.erb"
owner 'serviceaccount'
group 'serviceaccount'
mode '0644'
variables(
:service => serv,
:ports => port
)
end
end
It's not very idiomatic chef though.
gbaii
Updated on June 04, 2022Comments
-
gbaii almost 2 years
I have these arrays
services=["service1","service2","service3"] ports=[11001,11002,11003]
For each element of services I need to assign the correspondent element of ports in an conf.erb file. What I have until now is:
node['recipe']['services'].each do |serv| template "/etc/services/conf.d/service-#{serv}.conf" do source "service-#{serv}.conf.erb" owner 'serviceaccount' group 'serviceaccount' mode '0644' variables( :service => serv, :ports => node['services']['ports'] ) end end
It sounds bad and the result is bad.
The result should be 3 conf files:
service-service1.conf:
service-service1port 11001
service-service2.conf:
service-service2port 11002
service-service3.conf:
service-service3port 11003
Any help is appreciated.
Thank you, Gabriel