Set lookup_options to refine the result of a lookup

You can set lookup_options to further refine the result of a lookup, including defining merge behavior and using the convert_to key to get automatic type conversion.

The lookup_options format

The value of lookup_options is a hash. It follows this format:

 lookup_options:
  <NAME or REGEXP>:
    merge: <MERGE BEHAVIOR>
Each key is either the full name of a lookup key (like ntp::servers) or a regular expression (like '^profile::(.*)::users$'). In a module’s data, you can configure lookup keys only within that module’s namespace: the ntp module can set options for ntp::servers, but the apache module can’t.

Each value is a hash with either a merge key, a convert_to key, or both. A merge behavior can be a string or a hash, and the type for type conversion is either a Puppet type, or an array with a type and additional arguments.

lookup_options is a reserved key in Hiera. You can’t put other kinds of data in it, and you can’t look it up directly.

Location for setting lookup_options

You can set lookup_options metadata keys in Hiera data sources, including module data, which controls the default merge behavior for other keys in your data. Hiera uses a key’s configured merge behavior in any lookup that doesn’t explicitly override it.

Set lookup_options in the data sources of your backend; don’t put it in the hiera.yaml file. For example, you can set lookup_options in common.yaml.

Defining Merge Behavior with lookup_options

In your Hiera data source, set the lookup_options key to configure merge behavior:

# <ENVIRONMENT>/data/common.yaml
lookup_options:
  ntp::servers:     # Name of key
    merge: unique   # Merge behavior as a string
  "^profile::(.*)::users$": # Regexp: `$users` parameter of any profile class
    merge:          # Merge behavior as a hash
      strategy: deep
      merge_hash_arrays: true
Hiera uses the configured merge behaviors for these keys.

The lookup_options settings have no effect if you are using the deprecated hiera_* functions, which define for themselves how they do the lookup. To take advantage of lookup_options, use the lookup function or Automatic Parameter Lookup (APL).

Overriding merge behavior

When Hiera is given lookup options, a hash merge is performed. Higher priority sources override lower priority lookup options for individual keys. You can configure a default merge behavior for a given key in a module and let users of that module specify overrides in the environment layer.

As an example, the following configuration defines lookup_options for several keys in a module. One of the keys is overridden at the environment level – the others retain their configuration:

# <MYMODULE>/data/common.yaml
lookup_options:
  mymodule::key1:
    merge:
      strategy: deep
      merge_hash_arrays: true
  mymodule::key2:
    merge: deep
  mymodule::key3:
    merge: deep

# <ENVIRONMENT>/data/common.yaml
lookup_options:
  mymodule::key1:
    merge: deep  # this overrides the merge_hash_arrays true

Overriding merge behavior in a call to lookup()

When you specify a merge behavior as an argument to the lookup function, it overrides the configured merge behavior. For example, with the configuration above:

lookup('mymodule::key1', 'strategy' => 'first')

The lookup of 'mymodule::key1' uses strategy 'first' instead of strategy 'deep' in the lookup_options configuration.

Make Hiera return data by casting to a specific data type

To convert values from Hiera backends to rich data values, not representable in YAML or JSON, use the lookup_options key convert_to, which accepts either a type name or an array of type name and arguments.

When you use convert_to, you get automatic type checking. For example, if you specify a convert_to using type "Enum['red', 'blue', 'green']" and the looked-up value is not one of those strings, it raises an error. You can use this to assert the type when there is not enough type checking in the Puppet code that is doing the lookup.

For types that have a single-value constructor, such as Integer, String, Sensitive, or Timestamp, specify the data type in string form.

For example, to turn a String value into an Integer:

mymodule::mykey: "42"
lookup_options:
  mymodule::mykey:
    convert_to: "Integer"

To make a value Sensitive:

mymodule::mykey: 42
lookup_options:
 mymodule::mykey:
   convert_to: "Sensitive"

If the constructor requires arguments, specify type and the arguments in an array. You can also specify it this way when a data type constructor takes optional arguments.

For example, to convert a string ("042") to an Integer with explicit decimal (base 10) interpretation of the string:

mymodule::mykey: "042"
lookup_options:
  mymodule::mykey:
    convert_to:
      - "Integer"
      - 10
The default would interpret the leading 0 to mean an octal value (octal 042 is decimal 34):

To turn a non-Array value into an Array:

mymodule::mykey: 42
lookup_options:
 mymodule::mykey:
   convert_to:
     - "Array"
     - true

Related information