puppeterbhiera

Deep hiera lookup in a ruby template returns last result only


I have the following hiera:

profile::example::firewalls:
  - serverclass1:
    label: http
    port: 80
    label: https
    port: 443
  - serverclass2:
    label: ssh
    port: 22
    label: telnet
    port: 21

I try to call it in the following way in an erb template:

<% @example = scope().call_function('hiera',['profile::example::firewalls']) -%>
show me the array!
<%= @example %>

Oddly this returns the following:

+show me the array!
+[{"serverclass1"=>nil, "label"=>"https", "port"=>443}, {"serverclass2"=>nil, "label"=>"telnet", "port"=>21}]

Once I have a complete array I'll eventually use this within a for/each loop within ruby, but for the moment this seems to return just the final result and not everything I'd expect.


Solution

  • The problem begins in your YAML data structure, that contains duplicate "label" keys. That is why some of your data is missing in the output.

    (See this related Stack Overflow answer for more info.)

    Although it is not entirely clear what you are trying to do, it seems to me that you would be better with a YAML data structure like this:

    profile::example::firewalls:
      serverclass1:
        http: 80
        https: 443
      serverclass2:
        ssh: 22
        telnet: 21
    

    You could then iterate through that in the ERB template using code like:

    <% scope().call_function('lookup',['profile::example::firewalls']).each do |server_class, data| -%>
    Server class: <%= server_class %>
      <%- data.each do |key, value| -%>
      <%= key %> --- <%= value %>
      <%- end -%>
    <% end -%>
    

    Note also that I removed the deprecated hiera() function and replaced it with lookup().