Using the Hiera functions, the data stored in Hiera can be retrieved by the Puppet Master while compiling the catalog. In our manifests, we can have something like the following:
$dns_servers = hiera("dns_servers")
Note that the name of the Puppet variable need not be the same as that of the Hiera one, so the previous code can also be as follows:
$my_dns_servers = hiera("dns_servers")
This assigns to the variable $my_dns_servers the top value (the first one found while crossing the hierarchy of data sources) retrieved by Hiera for the key dns_servers.
We can also merge arrays and hashes here; so in order to retrieve an array of all the values in the hierarchy's data sources of a given key and not just the first one, we can use hiera_array() as follows:
$my_dns_servers = hiera_array("dns_servers")
If we expect a hash value for a given key, we can use the hiera() function to retrieve the top value found, or we can use hiera_hash() to merge all the found values in a single hash:
All these Hiera functions may receive additional parameters, which are as follows:
Second argument: If present and not blank, then this is the default value to use if no value is found for the given key.
Third argument: This overrides the configured hierarchy by adding a custom data source at the top of it. This might be useful in cases where we need to evaluate data using a logic that is not contemplated by the current hierarchy and for which it isn't worth the effort to add an extra layer in the global configuration.
The following code shows the usage of additional parameters:
With a hash, it is possible to express complex and structured data that has to be managed inside the Puppet code.
Remember that Hiera always returns the value of the first defined level keys, for example, we have a hash with nested hashes as shown in the following code:
Here, the custom network::interface define is expected to accept as an argument a hash to configure one or more network interfaces.
Puppet 3 automatic parameter lookup
With Puppet 3, Hiera is shipped directly with the core code, but the integration goes far beyond; an automatic Hiera lookup is done for each class' parameter using the key $class::$argument; this functionality is called data bindings or automatic parameter lookup.
For example, consider the following class definition:
This strong integration has definitely boosted the adoption of Hiera and is changing the way Puppet code is organized and classes are declared.
Before Puppet 2.6, we could declare classes by just including them, optionally, more than once in our catalog, using the following code line:
include openssh
We could also manage the behavior of the class just by setting variables and having them dynamically evaluated inside the class, with something like the following code:
This approach suffered the risks of having inconsistent values due to dynamic scoping of variables and parse ordering. Also, when using variables inside the module's code, it wasn't easy to understand what were the variables that could affect the class's behavior, and there was no public API that was easily accessible.
The introduction of parameterized classes in Puppet 2.6 allowed classes to expose their arguments in a clear way using the following code:
Now, we can pass them explicitly and consistently in a class declaration as shown:
class { 'openssh':
template => 'site/openssh/sshd_config.erb',
}
But the fact that we can declare a specific class using parameters only once in a node's catalog presented new challenges on how our custom code had to be organized; we could not include classes wherever needed, but we had to reorganize our manifests in order to avoid duplicate declarations.
From Puppet 3 onwards, it is possible to have the best of both worlds, as we can use the original way to include classes:
include openssh
We can use this statement in different parts of our manifests and be sure that the value of the template parameter is always looked up on the Hiera key openssh::template.