Using Hiera as node classifier in Puppet 5.0

As mentioned in Puppet doc Step 5: Assign the role to nodes, you can do classify nodes in 3 ways:

  • node declaration code in the main manifest ( site.pp or dir manifest).

  • External Node Classifier (like PE console /The Foreman / Puppet DashBoard)

  • Using Hiera to look up special classes and then include them

    use the lookup function to do a unique array merge on a special classes key, and pass the resulting array to the include function

The first choice seems is the traditional way, but when using Roles/Profiles Pattern, your node definitions are simply (only node/nodes group with roles). You may want to avoid writing code.

The second choice seems too heavy. Although you can avoid writing node definition code in these ENCs, does you need the whole ENC functionary and complexity?

The last option interested me most, it seems to be a lightweight way to do node classify with out code. But how to do it exactly? The document didn't say. After a little research I found how. And I think it's worth to share.

Basic usage

Basically, in your manifests/site.pp, this is all you need:

lookup('classes', Array[String], 'unique').include

Note 1: you don't even need to place it inside node default, although it did works as I tested.

node default {
  lookup().include
}

Note 2: A variation is this, it has the same functionality:

include(lookup('classes', Array[String], 'unique'))

What's going on there is when the catalog is compiling, Puppet will use lookup() (formally hiera_lookup() in Puppet 3.0) to get special data named classes from your hierarchy Hiera data, then declare them with include.

Now comes to the question, how to organize your Hiera hierarchy. Where to put your special named classes data?

Your can put classes to anywhere you like and reasonable. In most basic usage, for example, to mimic this line in manifests/site.pp

node 'postgres.example.com' {
  include role::postgres
} 

I use this line in data\nodes\postgres.example.com.yaml

---
classes:
  - role::postgres

More advanced usage

lookup() in Puppet 5.0 have an very interesting parameter knockout_prefix (only available to "deep" merge strategy ) to exclude things when do Hiera lookup. We can use it to exclude classes we don't want to declare which come from the upper Hiera hierarchy.

change your manifests/site.pp to this:

lookup({"name" => "classes", 
    "merge" => {
      "strategy" => "deep", 
      "knockout_prefix" => "!!"
    }
}).include

you can make sure your node didn't have role::mysql even high hireckey in heira specify it,

Given

# data\common.yaml
---
classes:
- role::mysql

AND

# data\nodes\postgres.example.com.yaml
---
classes:
  - role::postgres
  - !!role::mysql

Your node postgres.example.com will now only have one role: postgres.

Reference