I'm using hiera to assign classes like webserver
or dbserver
to my nodes. The webserver
class just includes apache and sets some config on it (e.g. port). Obviously I don't want to replicate this config for every node, so I put it in common.yaml. However, my common.yaml is getting big, so I want to split it up. I'd like to have one file containing the config for the webserver
role, another for the dbserver
role etc. I'm imagining my hiera.yaml to look something like this:
:hierarchy:
- "fqdn/%{::fqdn}"
- "role/%{ROLE}"
- common
Where the role
folder would contain files like webserver.yaml
, appserver.yaml
, dbserver.yaml
. I've seen various blog posts saying that the solution is to create a custom 'role' fact, but most of them achieve this by loading that fact from a file on the agent node (e.g from /etc/role
), which to me seems to defeat the point of puppet (I use puppet specifically so I don't have to log into each node and change some config every time I want it to have some new role).
To be clear, I don't want to have to edit files on the agent to get this to work, I want it all done using the config that's on the master.
I guess I could have something like the following and exhaustively list every role as an element in the hierarchy, but that doesn't seem that manageable.
:hierarchy:
- "fqdn/%{::fqdn}"
- "webserver"
- "appserver"
- "dbserver"
- common
Is there any way to solve this?
Hiera looks up data by following a hierarchy — an ordered list of data sources. Hierarchies are configured in a hiera. yaml configuration file. Each level of the hierarchy tells Hiera how to access some kind of data source.
The eyaml command is a command line interface for hiera-eyaml. It is used to create keys, encrypt and decrypt data, and act as a wrapper around a text editor.
The Hiera configuration file is called hiera. yaml . It configures the hierarchy for a given layer of data. Related information. Hiera configuration layers.
To be able to use $Role
in your hiera config, it needs to be supplied as a fact/variable, however there is a way to do this on the master instead of on the node. This is one of the things that External Node Classifiers can be used for.
Basically, you need to write a script that takes the node name and prints out yaml that includes the Role
parameter's value. For example, you could have one yaml file that is just a map of node names to roles, and then the script does a lookup and prints the result (as a parameter in the linked schema). Here is an example.
There are also more robust ENC's out there, if you are interested in new tooling. For example, Foreman gives you a web interface for grouping hosts together into similar roles, setting parameters to inject into puppet runs, etc.
I've come up with a solution for this. Only disadvantage is that the max number of roles is hardcoded. This will be better with hiera 3 until then try this:
/etc/puppet/hiera.yaml
---
:backends:
- yaml
:yaml:
:datadir: /etc/puppet/hieradata
:hierarchy:
- 'nodes/%{::clientcert}'
- 'roles/%{::role_4}'
- 'roles/%{::role_3}'
- 'roles/%{::role_2}'
- 'roles/%{::role_1}'
- common
/etc/puppet/manifests/site.pp
# Get roles
$roles = hiera_array('roles', [])
# Declare Roles in vars (not needed in puppet 4)
$role_1 = $roles[0]
$role_2 = $roles[1]
$role_3 = $roles[2]
$role_4 = $roles[3]
# Include Classes
hiera_include('classes')
/etc/puppet/hieradata/roles/webserver.yaml
---
classes:
- nginx
# put nginx config here
/etc/puppet/hieradata/nodes/your_node_name.yaml
---
roles:
- webserver
classes:
# put node specific stuff here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With