Working with the command line on a YAML backend

When we use a backend based on files such as JSON or YAML, which are the most commonly used, we have to recreate on the filesystem the hierarchy defined in our hiera.yaml file, the files that contain Hiera data must be placed in these directories.

Let's see Hiera in action. Look at the following sample hierarchy configuration:

:hierarchy:
  - "nodes/%{::fqdn}"
  - "env/%{::env}"
  - common

:yaml:
  :datadir: /etc/puppetlabs/code/hieradata

We have to create a directory structure as follows:

mkdir -p /etc/puppetlabs/code/hieradata/{nodes,env}

Then, work on the YAML files as shown:

vi /etc/puppetlabs/code/hieradata/nodes/web01.example42.com.yaml
vi /etc/puppetlabs/code/hieradata/env/production.yaml
vi /etc/puppetlabs/code/hieradata/env/test.yaml
vi /etc/puppetlabs/code/hieradata/common.yaml

These files are plain YAML files where we can specify the values for any Hiera-managed key. These values can be strings, arrays, or hashes:

vi /etc/puppet/hieradata/common.yaml
---
# A simple string assigned to a key
timezone: 'Europe/Rome'

# A string with variable interpolation
nagios_server: "nagios.%{::domain}"

# A string with another variable defined in Hiera (!)
dns_nameservers: "%{hiera('dns_servers')}"

# A string assigned to a key that maps to the
# template parameter of the openssh class (from Puppet 3)
openssh::template: 'site/common/openssh/sshd_config.erb'

# An array of values
ldap_servers:
  - 10.42.10.31
  - 10.42.10.32

# An array with a single value
ntp::ntp_servers:
  - 10.42.10.71

# A hash of values
users:
  al:
    home: '/home/al'
    comment: 'Al'
  jenkins:
    password: '!'
    comment: 'Jenkins'

Given the previous example, execute a Hiera invocation as follows:

hiera ldap_servers

It will return the following array:

["10.42.10.31", "10.42.10.32"]

If we define a different value for a key in a data source that is higher in the hierarchy, then that value is returned. Let's create a data source for the test environment as follows:

vi /etc/puppet/hieradata/env/test.yaml
---
ldap_servers:
- 192.168.0.31
users:
  qa:
    home: '/home/qa'
    comment: 'QA Tester'

A normal Hiera lookup for the ldap_servers key will still return the common value, as follows:

hiera ldap_servers
["10.42.10.31", "10.42.10.32"]

If we explicitly pass the env variable, the returned value is the one for the env test as follows:

hiera ldap_servers env=test
["192.168.0.31"]

If we have a more specific setting for a given node, that value is returned:

vi /etc/puppet/hieradata/nodes/ldap.example42.com.yaml
---
ldap_servers:
- 127.0.0.1
hiera ldap_servers fqdn=ldap.example42.com
["127.0.0.1"]

Note

We have seen that, by default, Hiera returns the first value found while traversing the data sources hierarchy, from the first to the last. When more backends are specified, the whole hierarchy of the first backend is fully traversed, then the same is done for the second and so on.

Hiera also provides some alternative lookup options. When we deal with arrays, for example, we can decide to merge all the values found in the hierarchy, instead of returning the first one found. Let's see how the result of the preceding command changes if the array lookup is specified (-a option):

hiera -a ldap_servers fqdn=ldap.example42.com
["127.0.0.1", "10.42.10.31", "10.42.10.32"]

Note that the value defined for the env=test case is not returned, unless we specify it:

hiera -a ldap_servers fqdn=ldap.example42.com env=test
["127.0.0.1", "192.168.0.31", "10.42.10.31", "10.42.10.32"]

When working with hashes, interesting things can be done.

Let's see what the value of the user's hash is for the test environment:

hiera users env=test
{"qa"=>{"home"=>"/home/qa", "comment"=>"QA Tester"}}

As it normally does, Hiera returns the first value it meets while traversing the hierarchy, but in this case, we might prefer to have a hash containing all the values found. Similar to the -a option for arrays, we have the -h option for hashes at our disposal:

hiera -h users env=test
{"al"=>{"home"=>"/home/al", "comment"=>"Al"},
 "jenkins"=>{"password"=>"!", "comment"=>"Jenkins"},
 "qa"=>{"home"=>"/home/qa", "comment"=>"QA Tester"}}

Note

Note that hashes are not ordered according to the matching order as arrays.

Let's make one further experiment, let's add a new user specific for our ldap.example42.com node and give different values to a parameter already defined in the common data source:

vi /etc/puppet/hieradata/nodes/ldap.example42.com.yaml
users:
  openldap:
    groups: 'apps'
  jenkins:
    ensure: absent

A hash lookup merges the found values as expected:

hiera -h users fqdn=ldap.example42.com env=test
{"al"=>{"home"=>"/home/al", "comment"=>"Al"},
 "jenkins"=>{"ensure"=>"absent"},
 "qa"=>{"home"=>"/home/qa", "comment"=>"QA Tester"},
 "openldap"=>{"groups"=>"apps"}}

Let's take a look at the parameters of the jenkins user; being defined both at node level and in the common data source, the returned value is the one for the higher data source in the hierarchy.

Hiera's management of hashes can be quite powerful, and we can make optimal use of it. For example, we can use them inside Puppet manifests with the create_resources function, with the hash of the users data and a single line of code as follows:

create_resources(user, hiera_hash($users))

Based on highly customizable Hiera data, we can manage all the users of our nodes.

Note

We can tune how Hiera manages the merging of hashes with the merge_behavior global setting, which allows deeper merging at single key levels. Read the official documentation at http://docs.puppetlabs.com/hiera/1/lookup_types.html#hash-merge for more details.

Quite often, we need to understand where a given key is set in our hierarchy and what values will be computed for it. The -d (debug) option is rather useful for this. The previous line will return the following output:

hiera -d -h users fqdn=ldap.example42.com env=test
DEBUG: 2013-12-07 13:11:07 +0100: Hiera YAML backend starting
DEBUG: <datetime>: Looking up users in YAML backend
DEBUG: <datetime>: Looking for data source nodes/ldap.example42.com
DEBUG: <datetime>: Found users in nodes/ldap.example42.com
DEBUG: <datetime>: Looking for data source env/test
DEBUG: <datetime>: Found users in env/test
DEBUG: <datetime>: Looking for data source common
DEBUG: <datetime>: Found users in common
{"al"=>{"home"=>"/home/al", "comment"=>"Al"},
 "jenkins"=>{"ensure"=>"absent"},
 "qa"=>{"home"=>"/home/qa", "comment"=>"QA Tester"},
 "openldap"=>{"groups"=>"apps"}}

This output also tells us where Hiera is actually looking for data sources.

In a real Puppet environment, it is quite useful to use the --yaml option, which, used with a real facts file of a node, allows us to evaluate exactly how Hiera computes its keys for real servers.

On the Puppet Master, the facts of all the managed clients are collected in $vardir/yaml/facts, so this is the best place to see how Hiera evaluates keys for different clients:

hiera --yaml /var/lib/puppet/yaml/facts/<node>.yaml ldap_servers

Hiera can use other sources to retrieve the facts of a node and return its key value accordingly. We can interrogate the Puppet Master's inventory service with the following command:

hiera -i ldap.example42.com ldap_servers

We can query mcollective (from a machine where the mco client is installed):

hiera -m ldap.example42.com ldap_servers
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset