Puppet. Iterate over a nested hash in ERB

17,672

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.

Share:
17,672
Daniel Cano
Author by

Daniel Cano

Updated on July 17, 2022

Comments

  • Daniel Cano
    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
    John Bollinger almost 8 years
    Note 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
    Matt Schuchard almost 8 years
    RE answer: you may want to mention -%> is because Puppet ERB trim mode is -. RE comment: he can also automatically generate that array with keys from puppetlabs-stdlib.
  • drewyupdrew
    drewyupdrew almost 8 years
    @JohnBollinger Very good point, edited my answer to include your tip. Thanks!
  • John Bollinger
    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
    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