How to reference hiera variable elsewhere in hiera?

852 Views Asked by At

We are using the roles pattern in puppet with hiera, meaning we have these lines in hiera.yaml:

- name: "Roles data"
  path: "roles/%{::server_role}.yaml"

We have a custom fact that produces the role name when facter runs, but we would like to move this into hiera. Instead of the server_role variable being produced by facter, we want to specify the server_role inside of hiera, and let that variable be referenced elsewhere in hiera. Something like this:

hiera.yaml:

- name: "Per-node data"
  path: "nodes/%{trusted.certname}.yaml"

- name: "Roles data"
  path: "roles/%{lookup(server_role)}.yaml"

nodes/hostname.yaml:

server_role: foo_bar

I have seen this question, which says to use hiera() or lookup() but when I try to use those, I get this error message:

Interpolation using method syntax is not allowed in this context

So how can I use a hiera variable that's defined elsewhere in hiera?

Edit:

The prototypical code examples for defining roles could use any fact that's known to facter, often giving examples that are based on hostname. When you can't embed server config into hostname, a common(ish) workaround is to write a file such as /etc/server_role, but it seems to defeat the purpose of config management, when you need to ssh into a machine and edit a file. As the other comments & answer here so far mentioned, you could use an ENC, but again, the goal here is not to have config stored outside of version control. In fact, we have foreman as an ENC and we make a practice to never use it that way because then upgrades and other maintenance become unsustainable.

We could write a class which will pick up data from hiera, write it to /etc/server_role, and on the next puppet run, facter will pick that up and send it back to hiera, so then we'll have the server_role fact available to use in hiera.yaml. As gross as this sounds, so far, it's the best known solution. Still looking for better answers to this question.

Thanks.

1

There are 1 best solutions below

0
On

As @MattSchuchard explained in comments, you cannot interpolate Hiera data into your Hiera config, because the config has to be known before the data can be looked up.

If you need a per-role level in your data hierarchy then an alternative would be to assign roles to machines via an external node classifier. You don't need it to assign any classes, just the server_role top-scope variable and probably also environment.

On the other hand, maybe you don't need a per-role level of your general hierarchy in the first place. Lots of people do roles & profiles without per-role data, but even if you don't want to do altogether without then it may be that module-specific data inside the module providing your role classes could be made to suffice.