Search code examples
puppet

When are puppet class parameters populated during catalogue compilation


I am having an issue with apparently non-deterministic behaviour of class parameters.
On some runs a used in a class is defined and contains the expected value, on others the variable isn't present in the scope at all.

$ puppet config print ordering --environment test
title-hash

On the puppet-master, so I don't believe it's a function of resource ordering (although that seems the most likely cause).

$ puppet --verison
3.7.4

I'm pushing to do an upgrade, but I need to resolve on this version (unless it's a puppet bug)

My module looks something like ...

$ cat mymodule/manifests/init.pp
class mymodule () {
  class { "mymodule::install":
    require => Class['mymodule::config'],
  }
}

$ cat mymodule/manifests/config.pp
class mymodule::config (
  $param1
) {
  notify{"config -- param1: ${param1}": }
}

$ cat mymodule/manifests/install.pp
class mymodule::install () {
  $local_var = $mymodule::config::param1
  notify{"install -- local_var: ${local_var}": }

  file {'/tmp/test_template.txt':
    content => template('mymodule/mytemplate.erb')
  }
}

$ cat mymodule/templates/mytemplate.erb
value = @local_var
All the things
<%= scope.to_hash.to_yaml %>

Both the module class and the config class are included in a node in the Foreman ENC. I've verified the YAML produced for the node and it looks correct.

The notify resources in the config and install classes are invariably printed config first followed by install, with the parameter always displayed in the config notification, but only sometimes in the install notification


Solution

  • You require => Class['mymodule::config'], but this has no effect on the order in which the parser reads your manifest. That is the issue here.

    You need to make sure that the class mymodule::config is declared before the parameter value is being looked up.

    If you rely on the resource-like declaration syntax instead of automatic parameter lookup through Hiera, then this can be arbitrarily complex to achieve.

    The randomness in your description makes me think that you rely on hashes in some capacity. Is Foreman passing in class names in a hash structure? If your Ruby is 1.8.x, you might wish to try a newer version (stable hash key order), although that will not be sufficient mitigation for your issue.

    For a comprehensive overview on the topic of evaluation order, peruse Henrik Lindberg's article Getting your Puppet Ducks in a Row.