4 Answers

You should not rely on node-level variables at all. I am not sure where I read or heard this but support for such variables might go away in future Puppet releases. This only leaves top-scope variables and proper facts, which is what you should be using.

Why not simply create a custom, external fact named role, making use of Facter's support for external facts? Something like this:

Of course this is impractical to do manually on multiple nodes so you either need to find a way to set up such facts at provisioning time, or with Puppet and a file resource, or "out of band", possibly using MCollective, Capistrano, or even parallel SSH.

That said, you seem to be making life for yourself more difficult by trying it this way.

Comments

I ended up being able to write a custom fact to define the role as a colleague decided to inform me our host names in the new environment would be predictable. Your info certainly helped me out though - thanks.

If you want to use "role" or other "runtime" defined variables in hiera, you can define them in the ENC. We use both "role" and "app_tier" in our hiera.yaml, both defined in "TheForeman" for the hostgroup, but I am sure that PE would work the same.

A slight variant on daff's solution would be to add this to your site manifest:

hiera_include('classes', [])

This saves the step of assigning the hiera lookup to a variable and then include $role. The empty array ensures that hiera_include does not fail when no hiera response is found, and also that pre-commit checks don't flag your site manifest as invalid (because pre-commit checks usually have no valid hiera source).

I tried Daff's solution for a while, but eventually ran into problems with hierarchy flexibility. Writing a fact based on hostname ended up being the solution that PuppetLabs support had me do and it has worked wonderfully.

Here's my code for {module_name}\lib\facter\application_tier.rb:

require 'facter'
Facter.add(:application_tier) do
setcode do
location = case Facter.value(:hostname)
when /dev(\d|)$/ then 'development'
when /test(\d|)$/ then 'test'
else 'production'
end
end
end

You can place the fact in any module, and it will be applied via pluginsync. If you're using Vagrant without a Puppet Master, like I am, then you'll need to define FACTERLIB too. I use a shell provisioner with the following line in it: