Puppet: v4.2.1
Hiera: v3.0.1
Facter: v3.0.2
Ruby: 2.1.6p336

Platform: Windows.

Came across an interesting behaviour when using hiera that was unexpected 
(to me anyway). I don't necessarily think its a bug, but I thought it worth 
sharing for others who may come across it. Keep in mind that this is just 
an example to illustrate the behaviour and not a recommendation about how 
to write Puppet/Hiera (maybe its even an anti-pattern !)

Lets say you have a class :

class hiera_binding_test (
    $version,
    $install_folder) {
  
  notice("version is: ${version}")
  notice("install_folder is: ${install_folder}")
}

a hiera.yaml :-

:hierarchy:
- common

:backends:
- yaml

:yaml:
  :datadir: E:/Temp/puppetTests/hiera_binding_test/hiera

and a hiera common.yaml :-

hiera_binding_test::version: '1.0'
hiera_binding_test::install_folder: 
"c:/apps/myapp/%{hiera_binding_test::version}/bin"

Note that in common.yaml that the 'install_folder' makes use of the 
'version' class param.

If when the hiera_binding_test class is called the 'version' param is 
passed explicitly (regardless of whether 'install_folder' is or not), the 
outcome is as expected :-

Notice: Scope(Class[Hiera_binding_test]): version is: 1.0
Notice: Scope(Class[Hiera_binding_test]): install_folder is: c:/apps/myapp/
1.0/bin

However, if we just use 'include' (which is obviously the patern we want to 
use by preference) :-

include hiera_binding_test

the outcome is NOT correct (version is not available) :-

Notice: Scope(Class[Hiera_binding_test]): version is: 1.0
Notice: Scope(Class[Hiera_binding_test]): install_folder is: c:/apps/myapp
//bin

So, even though the 'version' param was resolved by automatic parameter 
binding (as we can see from the first line) that value is NOT available to 
the the hiera expression for install_folder: 
c:/apps/myapp/%{hiera_binding_test::version}/bin

Interestingly, if I had implemented an inherited params.pp class, like this 
:-

class hiera_binding_test (
    $version,
    $install_folder) inherits hiera_binding_test::params {
  
  notice("version is: ${version}")
  notice("install_folder is: ${install_folder}")
}

class hiera_binding_test::params {
  $version                  = '1.1'
  $install_folder           = 'c:/apps/someotherapp/1.0/bin' 
}

a value for 'version' *would* be available (1.1) to the install_folder 
expression in hiera :-

Notice: Scope(Class[Hiera_binding_test]): version is: 1.0
Notice: Scope(Class[Hiera_binding_test]): install_folder is: c:/apps/myapp/
1.1/bin

Note that params.pp ONLY supplied the 'version' value for the hiera 
expression %{hiera_binding_test::version}. Values for the class params 
'version' and 'install_folder' STILL came from hiera, as we can see from 
the output.

Finally, if you are one of those people that prefer to NOT provide defaults 
for class params (so you can catch mis-configured classes at compile time), 
if you accidentally left out [say] 'install_folder' from common.yaml, you 
will still get the expected error despite the fact that it is declared in 
params.pp :

Error: Evaluation Error: Error while evaluating a Function Call, Must pass 
install_folder to Class[Hiera_binding_test] at E:/Temp/puppetTests/
hiera_binding_test/modules/hiera_binding_test/examples/init.pp:1:1 on node 
xxx

I'm not 100% sure why this behaviour is as it is (maybe something to do 
with precedence and/or the order of evaulation of classes (including 
inherited) versus when hiera comes in), not sure. But if anyone knows for 
certain why I would be interested.

Kind Regards

Fraser.

















-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/bb464aad-e9a2-4b3d-a87b-a90257dbcd2f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to