Ask Your Question

Hiera.conf 5 mapped_paths based on a Array fact from split string

asked 2017-05-04 10:45:22 -0500

Falkor gravatar image


I'm trying to setup a generic hierarchy based on Hiera 5 under the following assumptions:

  • a fact roles holds a comma-separated list of roles to use in hiera. Example: [ 'role1', 'role2' ].join(',') aka "role1,role2"
  • this roles fact is passed to puppet apply using the FACTER_roles environment variable (which explain why the array is not passed directly).

I'm trying now to setup the :hierarchysection of hiera.conf to handle properly facts.roles as an array to iterate on it using mapped_paths. Ideally, I would like to express this iteration as follows:

#  hiera.conf
version: 5      # below version 5 are deprecated starting puppet 4.9

### default datadir and backend for hierarchy levels.
defaults:  # Used for any hierarchy level that omits these keys.
  datadir: hieradata    # This path is relative to hiera.yaml's directory.
  data_hash: yaml_data  # Use the built-in YAML backend.
  - name: "Per-node data"                  
    path: "nodes/%{trusted.certname}.yaml"
  - name: "Role Specific data"
    mapped_paths: [ "%{split(facts.roles, ',')}", role, "role/%{role}.yaml" ]
  - name: "Common data"
    path: "common.yaml"

Assuming the above setup, I'm expecting to see hiera "loading" the following hiera files:

  • hieradata/role/role1.yaml
  • hieradata/role/role2.yaml
  • hieradata/common.yaml

However it does not work: I end with a strange message ==> master: Error: Evaluation Error: Error while evaluating a Function Call, Lookup of key 'noop_mode' failed: Syntax error in string: mapped_path[0] at /tmp/vagrant-puppet/manifests-a11d1078b1b1f2e3bdea27312f6ba513/default.pp:33:14 on node

I don't see the proper way to define a call to the split function within hiera.yaml. Can anyone help me ?

Appendix: mapped_paths

The mapped_paths key must contain three string elements, in the following order: A scope variable that points to a collection of strings. The variable name that will be mapped to each element of the collection. A template where that variable can be used in interpolation expressions. For example, a fact named $services contains the array [“a”, “b”, “c”]. Then this configuration:

mapped_paths: [services, tmp, "service/%{tmp}/common.yaml"]

has the same results as if paths had been specified to be [service/a/common.yaml, service/b/common.yaml, service/c/common.yaml].

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted

answered 2017-05-05 11:30:43 -0500

smarlow gravatar image

updated 2017-05-05 11:33:46 -0500

You can invoke a function in an interpolation token in Hiera, but I think that that is limited only to lookup functions (e.g. scope(), hiera(); see here).

Consequently I don't think there's a good way to split directly inside of hiera.yaml. Instead I would suggest making sure that the fact is already an array when you arrive that that point. Since you're already relying on something manually set on the end machine to dictate the roles it would probably be easiest to just use an external fact.

For example, if you had /etc/puppetlabs/facter/facts.d/roles.yaml with the following content:

roles: ['role1', 'role2']

Facter would pick up this fact as an array and you should be able to use it directly.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-05-04 10:45:22 -0500

Seen: 55 times

Last updated: May 05