Puppet. Iterate over a nested hash in ERB
Your template looks fine for the most part, but few things here. First off, you may not be able to use periods for your variable names, but more importantly, don't forget commas to separate key/value pairs:
$database_profile_array = [cpu,sysctl]
$database_profile_hash =
{
cpu => {
governor => ondemand,
energy_perf_bias => powersave,
},
sysctl => {
kernel_sched_min_granularity_ns => 10000000,
kernel_sched_wakeup_granularity_ns => 15000000,
kernel_msgmnb => 6,
}
}
In your template, you're forgetting the equal signs, and you also might want to omit new line characters for each iteration by using -%>
:
<% @database_profile_array.each do |arrayValue| -%>
[<%= arrayValue %>]
<% database_profile_hash[arrayValue].each do |key,value| -%>
<%= key %>=<%= value %>
<% end %>
<% end -%>
Edit: OP, note the comments others have left. If the iteration sequence doesn't matter, you don't need the separate array $database_profile_array
to reference the keys, rather you can iterate the hash directly:
<% @database_profile_hash.each do |key, hash| -%>
[<%= key %>]
<% hash.each do |key,value| -%>
<%= key %>=<%= value %>
<% end %>
<% end -%>
Also, the -%>
erb puppet trim tag is documented here.
Daniel Cano
Updated on July 17, 2022Comments
-
Daniel Cano almost 2 years
I am starting to develop in puppet (ruby) and I have the following problem.
I have the current hash that I want to iterate in a template file.
$database_profile_hash = { cpu => { governor => ondemand energy_perf_bias => powersave } sysctl => { kernel.sched.min.granularity.ns => 10000000 kernel.sched.wakeup.granularity.ns => 15000000 kernel.msgmnb => 6 } ... }
And my current template is the following:
<% @database_profile_array.each do |arrayValue| %> [<%= arrayValue %>] <% database_profile_hash[arrayValue].each do |key,value| %> <%= key %> <%= value %> <% end %> <% end %>
To iterate the array I am trying to use an array to store all the first level names and then use it to iterate the hash:
$database_profile_array = [cpu,sysctl,...]
But I am not able to make it work and I am looking for an exit like this:
[cpu] governor=ondemand energy_perf_bias=powersave [sysctl] vm.laptop_mode=5 vm.dirty_writeback_centisecs=1500 kernel.nmi_watchdog=0
What I am doing wrong in the template? There is a way to pass the content of the variable "arrayValue" to iterate the hash?
Thanks a lot in advance...
-
John Bollinger almost 8 yearsNote also that you don't necessarily need a separate array of the top-level keys. You can iterate the top-level hash to get those keys and their associated hashes (values). The separate array is useful only if you want to specify the exact sequence in which the sections are presented or if you want to select an externally-directed subset of the top-level keys.
-
Matt Schuchard almost 8 yearsRE answer: you may want to mention
-%>
is because Puppet ERB trim mode is-
. RE comment: he can also automatically generate that array withkeys
frompuppetlabs-stdlib
. -
drewyupdrew almost 8 years@JohnBollinger Very good point, edited my answer to include your tip. Thanks!
-
John Bollinger almost 8 years@MattSchuchard, yes, he can generate the array of keys via stdlib's
keys()
function. That might be useful if he wanted sometimes to be selective and sometimes all-inclusive. If he wants always to be all-inclusive, however, then it is better to get rid of the array altogether. -
Matt Schuchard almost 8 years@JohnBollinger yes I know, and he probably knows too, but I mentioned that in case he would be interested in a dynamic method for generating the array he was manually hardcoding, so he knows that ability exists for the future