Automatic parameter binding value is NOT available elsewhere in hiera

26 views
Skip to first unread message

Fraser Goffin

unread,
Sep 9, 2015, 6:44:57 AM9/9/15
to Puppet Users
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.

















jcbollinger

unread,
Sep 9, 2015, 9:14:31 AM9/9/15
to Puppet Users


I hadn't heard about this one before, but I can't say it's very surprising.  This looks like a variation on the longstanding issue that class parameter defaults cannot safely rely on the values of other parameters of the same class.  Doing so works as desired in some cases, but not in others.  It basically comes down to evaluation order, the details of which are unspecified in this area.  I don't expect any change in this area, so I'd go along with your anti-pattern theory.


John

Reply all
Reply to author
Forward
0 new messages