简体   繁体   中英

Puppet 5 Iterate over Hash

How to iterate over below hiera in Puppet 5 using iteration ( not defined resources)

Edited with more information

I would like to create a file with config text as contents passed to template

Here is what i have working.

Hiera

appname::app_config:
  "/tmp/application.properties":
    config_text:
      - "# First Line"
      - "Second Line"
      - ""
      - "So forth"

  "/tmp/database.properties":
    config_text:
      - "Test Line"
      - "Another Test Line"

Puppet Iteration config of that hiera

  $appname_config.each | $config_file, Hash $config_text| {
    file { "$config_file" :
      ensure => present,
      content => template('modulename/generic_config.epp'),
      }
    }

Template

<% @config_text.each do |key, value| -%>
<% value.each do |key,value| -%>
<%= key %>
<% end %>
<% end -%>

But I am sorta required to use below format hiera

appname::app_config:
  file: "/tmp/dummy.config"
  config_text:
        - "Application Properties"
        - "TimePeriod = 1"
 
   file: "/tmp/second.txt"
   config_text:
        - "Application Properties"
        - "TimePeriod = 1"

Thanks in advance

Nothing from the first block is going to get returned, for example the file is only going to return /tmp/second.txt , it's a hash and you have duplicate keys so it's just going to get overwritten. To get a better idea of what's going on you may want to run something like

class appname  (
  $app_config
){
  notify { $app_config[file]: }
  $app_config[config_text].each |$item| {
    notify { $item: message => $item }
  }
}

It's a hash so you can access anything in there using it's key.

But I am sorta required to use below format hiera

appname::app_config: file: "/tmp/dummy.config" config_text: - "Application Properties" - "TimePeriod = 1" file: "/tmp/second.txt" config_text: - "Application Properties" - "TimePeriod = 1"

You cannot usefully use that format to convey information about more than one file, because that would require using duplicate hash keys, as indeed your example demonstrates. About the closest you can come would be to structure the data as an array of hashes instead of a single hash: *

appname::app_config:
   - file: "/tmp/dummy.config"
     config_text:
        - "Application Properties"
        - "TimePeriod = 1"
   - file: "/tmp/second.txt"
     config_text:
        - "Application Properties"
        - "TimePeriod = 1"

You could then iterate over that in your manifest like so:

  $appname::app_config.each | $config_hash | {
    $config_file = $config_hash['file']
    $config_text = $config_hash['config_text']

    file { "$config_file" :
      ensure  => 'present',
      content => template('modulename/generic_config.erb'),
    }
  }

Additionally, the config_text of each entry is presented as an array of strings, not only in my example but also in both of yours. Your template attempts to iterate over it as if it were a hash of hashes, however, and that will not work. This would be a more appropriate template:

<% @config_text.each do |line| -%>
<%= line %>
<% end -%>

But if all you need to do is output a series of lines like that, then a template is way overkill. Puppet's built in join function would do that more clearly, and using it would relieve you of maintaining a separate template:

# ...
content => join($config_text, "\n"),
# ...

* But if I were choosing an Hiera representation for this data then I would go with something closer to the form you say you have working for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM