Merge behaviors

There are four merge behaviors to choose from: first, unique, hash, and deep.

When specifying a merge behavior, use one of the following identifiers:

  • 'first', {'strategy' => 'first'}, or nothing.
  • 'unique' or {'strategy' => 'unique'}.
  • 'hash' or {'strategy' => 'hash'}.
  • 'deep' or {'strategy' => 'deep', <OPTION> => <VALUE>, ...}. Valid options:
    • 'knockout_prefix' - String; disabled by default.
    • 'sort_merged_arrays' - Boolean; default is false
    • 'merge_hash_arrays' - Boolean; default is false

First

A first-found lookup doesn’t merge anything: it returns the first value found for the key, and ignores the rest. This is Hiera’s default behavior.

Specify this merge behavior with one of these:

  • 'first'

  • {'strategy' => 'first'}

  • lookup($key)
  • Nothing (because it’s the default)

Unique

A unique merge (also called an array merge) combines any number of array and scalar (string, number, boolean) values to return a merged, flattened array with all matching values for a key. All duplicate values are removed. The lookup fails if any of the values are hashes. The result is ordered from highest priority to lowest.

Specify this merge behavior with one of these:

  • 'unique'

  • lookup($key, { 'merge' => 'unique' })
  • {'strategy' => 'unique'}

Hash

A hash merge combines the keys and values of any number of hashes to return a merged hash of all matching values for a key. Every match must be a hash and the lookup fails if any of the values aren’t hashes.

If multiple source hashes have a given key, Hiera uses the value from the highest priority data source: it won’t recursively merge the values.

Hashes in Puppet preserve the order in which their keys are written. When merging hashes, Hiera starts with the lowest priority data source. For each higher priority source, it appends new keys at the end of the hash and updates existing keys in place.

# web01.example.com.yaml
mykey:
  d: "per-node value"
  b: "per-node override"
# common.yaml
mykey:
  a: "common value"
  b: "default value"
  c: "other common value"


`lookup('mykey', {merge => 'hash'})
Returns the following:
{
  a => "common value",
  b => "per-node override", # Using value from the higher-priority source, but
                            # preserving the order of the lower-priority source.
  c => "other common value",
  d => "per-node value",
}
Specify this merge behavior with one of these:
  • 'hash'

  • lookup($key, { 'merge' => 'hash' })
  • {'strategy' => 'hash'}

Deep

A deep merge combines the keys and values of any number of hashes to return a merged hash. It contains an array of class names and can be used as a lightweight External Node Classifier (ENC).

If the same key exists in multiple source hashes, Hiera recursively merges them:

  • Hash values are merged with another deep merge.
  • Array values are merged. This differs from the unique merge. The result is ordered from lowest priority to highest, which is the reverse of the unique merge’s ordering. The result is not flattened, so it can contain nested arrays. The merge_hash_arrays and sort_merged_arrays options can make further changes to the result.
  • Scalar (String, Number, Boolean) values use the highest priority value, like in a first-found lookup.

Specify this merge behavior with one of these:

  • 'deep'
  • include(lookup($key, { 'merge' => 'deep' }))
  • {'strategy' => 'deep', <OPTION> => <VALUE>, ...} — Adjust the merge behavior with these additional options:
    • 'knockout_prefix' (String) - Use with a string prefix to indicate a value to remove from the final result. Note that this option is disabled by default due to a known issue that causes it to be ineffective in hierarchies more than three levels deep. For more information, see Puppet known issues.
    • 'sort_merged_arrays' (Boolean) - Whether to sort all arrays that are merged together. Defaults to false.
    • 'merge_hash_arrays' (Boolean) - Whether to deep-merge hashes within arrays, by position. For example, [ {a => high}, {b => high} ] and [ {c => low}, {d => low} ] would be merged as [ {c => low, a => high}, {d => low, b => high} ]. Defaults to false.

Unlike a hash merge, a deep merge can also accept arrays as the root values. It merges them with its normal array merging behavior, which differs from a unique merge as described above. This does not apply to the deprecated Hiera 3 hiera_hash function, which can be configured to do deep merges but can’t accept arrays.