I used to use Puppet a lot, from 0.x up to around the release of 1.0, then changed jobs but now I'm back at it. Hiera in Puppet is new to me (along with a ton of other stuff).
Am I correct in the understanding that it is basically impossible to assign classes to groups of nodes based on host name (or cert name) pattern matching with Hiera?
I used to, for example, assign ntp server classes if the host was something like "ntp1.foo.com". This is pretty easy with straight node
definitions in site.pp
, and I'm trying to move this concept into a Hiera-based world. I have Hiera assigning other classes and was hoping to lump all of those assignments into one place.
The only way I have found to do this to set a parameter via some non-Hiera means and using its value in Hiera to match a path. For example, in my enc
script I export a parameter like this:
echo "parameters:"
if [ ... ]; do echo " ntpRole: server; else echo " ntpRole: client"; fi
and in Hiera I would do something like:
- "roles/ntp-%{ntpRole}"
I think one could also do this via a custom fact.
This works, but seems like a kludge. Is there a better/recommended alternative?
One problem with this is that every node must have a value (everything is assigned a ntp-something class). This works for NTP, since all the machines are either an NTP client or server, but for something existential it doesn't.
For example: a web server role. Some machines wouldn't be web servers, so I don't want to include that class, but for others I do, and I don't really want to have to maintain that in per-node files and don't really want to have empty *-none
role classes everywhere (e.g. web-none
vs. web-server
). I want all machines named www*
, or based on some other criteria, to load the roles/web
class. Can this be done with Hiera?
If your roles have a relation to server facts, then you can use a custom fact to assign roles. Since you said you were formerly doing node classification based on server name, I will assume this is the route you want to go.
# custom role fact
require 'facter'
Facter.add(:role) do
case Facter.value(:hostname)
when /ntp/ then 'ntp-server'
when /www/ then 'web-server'
else abort 'Hostname does not provide a role.'
end
end
You can then set up a hiera config like this:
:hierarchy:
- "nodes/%{::trusted.certname}"
- role/%{role}
- "common"
Inside your role data files, you can provide an array of class names:
# role/web-server.yaml
classes:
- web-server
Inside your main manifest (normally $environment/manifest/site.pp
:
# if no classes array, traverse the else block
if hiera('classes', false) {
hiera_include('classes')
}
else {
# logic for your 'none' situations since the classes array was not present
}
Check this for hiera_include
information: https://docs.puppet.com/hiera/3.2/puppet.html#assigning-classes-to-nodes-with-hiera-hierainclude. Note it will merge in classes from your specific fqdn.yaml
data files also.
This will give you the functionality you are requesting and uses Hiera to include classes by node grouping/hostname.