Search code examples
loopspuppethiera

Puppet 3.8.# inline_template fails to pickup hieradata


I am working on creating a puppet module. My puppet version is 3.8.7 and upgrade is out of the question. My hieradata and relative contents of init.pp file is copied below for reference.

---------Hiera Data---------
my_hieradata:
  blue: http://foobar.com
  red: http://barfoo.com
----------------------------

---------My_init.pp---------
$my_hieradata= hiera('my_hieradata') 
.
. 
if $my_hieradata{    $my_site = inline_template('<% if @my_hieradata-%><% @my_hieradata.each do |key, value| -%><%= key %>,<% end -%><% end -%>')
  $my_array = split($my_site,',')
  mymodule::my.log { $my_array:;
  }
.
.
.
define mymodule::my_log {
  file { '/foo/bar/log/${name}.log':
    ensure => 'file',
    mode   => '0644',
    owner  => 'zeus',
    group  => 'zeus',
  }
}
----------------------------

I was hoping this would produce two files as per my hieradata

/foo/bar/log/blue.log
/foo/bar/log/red.log

however when I do puppet run it fails with below error.

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate declaration: File[/foo/bar/log/${name}.log] is already declared in file /etc/puppet/modules/mymodule/manifests/init.pp:100; cannot redeclare at /etc/puppet/modules/mymodule/manifests/init.pp:100 on node cc1.prodops.tllsc.net
Warning: Not using cache on failed catalog

From the error i can see that the variable ${name} fails to pickup value from the hieradata. It treats the varibale as string and prints it as it is. Request the experts here to help me why the varibale is not picking up the value from hiera.


Solution

  • The main issue is that you are using the literal string (single quotes) as the title to your file object instead of an interpolated string (double quotes). update your file object to the following an i think it should work

    define mymodule::my_log {
      file { "/foo/bar/log/${name}.log":
        ensure => 'file',
        mode   => '0644',
        owner  => 'zeus',
        group  => 'zeus',
      }
    }
    

    however as Matt Schuchard mentioned if you have the future parser you can make use of the keys functions and simplify your code to

    my_hieradata:
      blue: http://foobar.com
      red: http://barfoo.com
    
    define mymodule::my_log {
      file { "/tmp/${name}.log":
        ensure => 'file',
        mode   => '0644',
      }
    }
    $my_hieradata = hiera('my_hieradata')
    mymodule::my_log{$my_hieradata.keys(): }