Grouping and classifying nodes

Configure nodes by assigning classes, parameters, and variables to them. This is called classification.

To classify nodes, you must:
  1. Create node groups to contain nodes and preferences (classes, parameters, and variables) you want to apply to nodes in the group. Make sure you understand the Best practices for classifying node groups and the difference between Environment versus classification node groups.
  2. Add nodes to groups.
  3. Declare classes and Define data used by node groups. You might need to Enable data editing in the console.

Nodes can belong to multiple node groups, and they inherit classes, class parameters, and variables from all node groups they belong to.

After classifying nodes, you can View nodes in a node group and Make changes to node groups.

How node group inheritance works

Node groups are organized in a parent-child-grandchild hierarchy. When added to a group, nodes inherit classes, parameters, variables, and rules from their immediate node group and the group's ancestors.

  • Classes: If a class is declared in an ancestor node group, the class is inherently declared in all node groups descending from that group.
  • Class parameters and variables: Descendant node groups inherit class parameters and variables from ancestors unless a different value is set in a descendant node group.
    CAUTION: Because nodes can belong to multiple groups in separate hierarchies, it’s possible for two node groups to contribute conflicting variable or class parameter values. Conflicting values cause Puppet runs on agent nodes to fail.
  • Dynamic node group rules: To belong to a group, a node must match all rules in the immediate group and the rules in the ancestor groups. Use rule inheritance to refine group membership: Create broad rules for parent groups (such as an OS family) and more specific rules for the child groups that refine the parent group rules (such as specific platforms or versions). This way you can take a large, generic set of nodes and filter them into specific child groups.
Tip: In the console, go to Node groups to see how node groups are related. The Node groups page shows a hierarchical view of your node groups. From the command line, you can use the group-children endpoint to review group lineage.

Best practices for classifying node groups

To organize node groups, start with the high-level functional groups that reflect the business requirements of your organization, and work down to smaller segments within those groups.

For example, if a large portion of your infrastructure consists of web servers, create a node group called web servers and add any classes that need to be applied to all web servers.

Next, identify subsets of web servers that have common characteristics but differ from other subsets. For example, you might have production web servers and development web servers. So, create a dev web child node group under the web servers node group. Nodes that match the dev web node group get all of the classes in the parent node group in addition to the classes assigned to the dev web node group.

Environment versus classification node groups

Environment node groups assign environments to nodes, such as test, development, or production.

Important: A node can belong to only one environment node group. If a node is added to more than one environment group, classification errors occur. See this classification conflict article for more information.
Each environment node group:
  • Must correspond to a Git branch in a control repo you want to use for targeted code deployments. The Git branch and environment group must have the same name.
  • Must be a child of the All Environments node group (or whichever is the highest-level environment node group in your installation). Furthermore, your environment node groups, themselves, must not have any child groups, except one-time run exception subgroups used for canary testing.
  • Must not include classes or configuration data.

Classification node groups assign classification data to nodes, including classes, parameters, and variables. A node can belong in more than one classification group.

Each classification node group:
  • Must be a child of All Nodes or another classification group.
  • Must not be specified as an environment group in the group metadata.

Create node groups

Use the console to create node groups to assign either an environment or classification.

Create environment node groups

Create custom environment node groups so you can target Puppet code deployments.

Before you begin
Each environment node group must correspond to a Git branch in a control repo you want to use for targeted code deployments. The Git branch and environment group must have the same name. Make sure you know the names of the corresponding Git branches for your environment node groups.
  1. In the console, click Node groups, and click Add group.
  2. Specify options for the new node group:
    • Parent name: Select the top-level environment node group in your hierarchy, such as All environments or Production environment (depending on your installation's configuration).
      Important: Each environment mode group must be a child of the highest-level environment node group in your installation.
    • Group name: Enter a name corresponding to the Git branch in your control repo that you want to use for targeted code deployments for this environment.
      Important: The Git branch and environment group must have the same name.
    • Environment: Select the environment that you want to assign to the nodes in this node group.
    • Environment group: Select this option.
  3. Click Add.
What to do next
Add nodes to your environment node group to control which environment each node belongs to. Each node can belong to only one environment node group.

Create classification node groups

Classification node groups assign classification data to nodes.

  1. In the console, click Node groups, and click Add group.
  2. Specify options for the new node group:
    • Parent name: Select the classification node group that you want to be the parent of your new classification node group. Classification node groups inherit classes, parameters, and variables from their parent node group. The default parent node group is the All Nodes node group.
    • Group name: Enter a name that describes the classification node group's role. For example, Web Servers.
    • Environment: Specify an environment to limit the classes and parameters available for selection in this node group.

      Specifying the Environment in a classification node group only filters the available classes and parameters. It does not assign an environment to the nodes in the group (as is the case in environment node groups).

    • Environment group: Do not select this option.
  3. Click Add.
What to do next
Dynamically or statically add nodes to the classification node group.

Add nodes to a node group

There are two ways to add nodes to a node group.

You can Statically add individual nodes to a node group or use fact-based rules to Dynamically add nodes to a node group. With dynamic node group rules, Puppet Enterprise (PE) automatically adds and removes nodes from your groups based on the rules you set, whereas you must manually add or remove static (pinned) nodes.

If you expect a node to belong to multiple node groups, make sure you understand How node group inheritance works. If nodes inherit conflicting values from different groups, then Puppet runs on agent nodes fail.

Statically add nodes to a node group

You can pin individual nodes to node groups.

If you need to add a lot of nodes to a group, it is more useful to Dynamically add nodes to a node group with logical rules that automatically add and remove nodes from your node groups. Pinning individual nodes to groups is only recommended if the node group only has a few nodes or if you need to add some specific nodes that weren't captured by the group's dynamic rules.

Pinning a node is the same as creating a rule for certname = <EXACT_NODE_CERTNAME>, and Puppet Enterprise (PE) processes this rule along with the group's other fact-based rules (if there are any).

Important: A pinned node remains in the node group until you manually remove it.
  1. In the console, click Node groups and select the node group that you want to pin the node to.
  2. On the Rules tab, enter the node's certname in the Certname field.
  3. Click Pin node and commit changes.
Results
Pinned nodes are listed under the Certname field.

Dynamically add nodes to a node group

Rules are the most powerful and scalable way to include nodes in a node group. Rules use facts to identify nodes to include in a group.

Rules are based on facts, such as operating system, BIOS version, hardware model, UUID, or time zone. In addition to most core facts, you can also use structured and trusted facts for node group rules.

As long as a node matches the node group's rules, the node is included in the group and classified with the node group's classification data (classes, parameters, and variables). If the node changes and no longer matches the node group's rules, the node is no longer considered part of the group, and the node group's classification data no longer applies to the node.

  1. In the console, click Node Groups and select the node group you want to add nodes to.
  2. Think about which nodes you want to add to this group and the characteristics of those nodes. Rules are based on Facter facts, so you must determine which facts describe the nodes you want (or don't want) in this group. Then, you can create logical rules based on those facts.
    Rules can be inclusive or exclusive, and you can apply multiple rules to each node group. When you have multiple rules, you can require nodes to match all rules or only match one of the rules.
  3. On the Rules tab, create a fact-based rule, and click Add Rule.
    For example, this rule specifies that nodes in the group must have a Red Hat OS:
    • Fact: osfamily
    • Operator: =
    • Value: RedHat

    Writing node group rules explains the various Operator options and how to select core, structured, and trusted facts.

  4. If needed, add more rules, and select how to apply the rules: select to Or, select to
    • Nodes must match all rules: Combine rules for more granular node selection.
    • Nodes may match any rule: Add a variety of rules to select nodes with different characteristics.
    Tip: If you have a few individual nodes that you aren't able to capture with rules, you can Statically add nodes to a node group in addition to your dynamic rules.
  5. Commit changes.

Writing node group rules

To create a dynamic node group rule, you must specify a Fact, Operator, and Value.

These three fields are required to Dynamically add nodes to a node group.

The Fact field specifies the fact you want to the rule to use. You can select from the dropdown list of known facts, enter part of a string to filter the list, or use structured or trusted facts. For structured and trusted facts, select the initial value from the dropdown list, then type the rest of the fact:
  • To descend into a hash, use periods (.) to designate path segments, such as os.release.major or trusted.certname.
  • To specify an item in an array, put square brackets around the item's numerical index, such as processors.models[0] or mountpoints./.options[0].
  • To identify path segments that have periods, dashes, spaces, or UTF characters, put single or double quotes around the segment, such as trusted.extensions."1.3.6.1.4.1.34380.1.2.1".
  • To use trusted.extensions short names, append the short name after a second period, such as trusted.extensions.pp_role.
Important: When you enter structured and trusted facts, PE doesn't provide suggestions as you type (except for the top-level name key), nor does it verify that the facts exist. After you add a rule that uses a structured or trusted fact, check the number of Node matches to verify that the fact is generating matches and was entered correctly.
The Operator field describes the relationship between the Fact and the Value. It defines how the rule uses the fact (inclusively, exclusively, exactly, minimum, maximum, and so on). Operators include:
  • =: Is
  • !=: Is not
  • ~: Matches regex
  • !~: Does not match regex
  • >: Greater than
  • >=: Greater than or equal to
  • <: Less than
  • <=: Less than or equal to
The >, >=, <, and <= operators require facts that have numeric values, such as dates, times, or version numbers.

The ~ and !~ operators require a regular expression (regex) Value and are useful for matching highly-specific node facts (for example, you want to find nodes with UUIDs starting with 9999*)

The Value field describes the relevant Fact value. Depending on the Fact and Operator, the Value can be a string, number, or regular expression.

Together these fields create a logical rule that PE uses to find matching nodes. If you have multiple dynamic rules for one node group, you can choose whether Nodes must match all rules or if Nodes may match any rule to be added to the group.

Using structured and trusted facts for node group rules

Structured facts group related facts, and trusted facts are a type of structured fact.

Structured facts group related facts in a hash or array. For example, the os structured fact contains multiple individual facts about the operating system, such as architecture, family, and release. In the Puppet Enterprise (PE) console, when you view a node's facts, structured facts are surrounded by curly braces.

Trusted facts are a type of structured fact where the facts are immutable and extracted from a node’s certificate. Because these facts can’t be changed or overridden, trusted facts enhance security by verifying a node’s identity before sending sensitive data in its catalog.

You can use structured and trusted facts in dynamic node group rules.
Restriction: If you use trusted facts to specify certificate extensions, in order for this fact to function properly in a node group rule, you must use short names for Puppet-specific registered IDs and numeric IDs for private extensions. Private extensions require numeric IDs whether or not you specify a short name in the custom_trusted_oid_mapping.yaml file.

Declare classes

Classes are blocks of Puppet code that configure nodes and assign resources to nodes.

Before you begin
The class that you want to apply must exist in an installed module. You can download modules from the Puppet Forge or create your own module. For information about modules and installing modules, refer to the Modules overview and Installing and managing modules from the command line in the Puppet documentation.
  1. In the Puppet Enterprise (PE) console, click Node groups and select the node group that you want to add the class to.
  2. On the Classes tab, select the class to add.
    Tip: The Add new class field suggests classes that your PE primary server knows about and that are available in the environment defined in the node group's settings.
    If classes are missing, check that:
    • You have correctly installed the module containing the class you want to assign.
    • The module is installed in the environment defined in the node group's settings. For information about the Environment setting for classification node groups, refer to Create classification node groups.
    • Your Puppet code has been deployed since installing the module or making changes to node groups. If you're using Code Manager or r10k for Managing and deploying Puppet code, you might need to trigger a code deployment.
  3. Click Add class and then commit changes.
    Tip: Classes don’t appear in the class list until they’re retrieved from the primary server and the environment cache is refreshed. By default, both of these actions occur every three minutes. To override the default refresh period and force the node classifier to retrieve the classes from the primary server immediately, click the Refresh button.

Enable data editing in the console

In new Puppet Enterprise (PE) installations, you can, by default, edit configuration data in the console. If you upgraded from an earlier PE version where you hadn't already enabled editing of configuration data, you must use Hiera to manually enable Classifier Configuration Data.

  1. On your primary server, open the hiera.yaml file located at: /etc/puppetlabs/puppet/hiera.yaml.
  2. Add the following to the hiera.yaml file:
    hierarchy: 
    - name: "Classifier Configuration Data"
      data_hash: classifier_data

    Place additional hierarchy entries, such as hiera-yaml or hiera-eyaml under the same hierarchy key, below the Classifier Configuration Data entry.

  3. To allow users to edit the configuration data in the console, add the Set environment and Edit configuration data permissions to any user groups that need to set environment parameters or modify class parameters.
  4. If your environment is configured for disaster recovery or has compilers, update hiera.yaml on your replica and compilers, respectively.

Define data used by node groups

The console offers multiple ways to specify data used in your manifests.

Important: You can structure parameters and variables as JSON, but, if they can't be parsed as JSON, they're treated as strings.

Set configuration data

Configuration data set in the PE console is used for automatic parameter lookup in the same way that Hiera data is used. Console configuration data takes precedence over Hiera data, but you can combine data from both sources to configure nodes.

Tip: In most cases, setting configuration data in Hiera is the more scalable and consistent method, but there are some cases where the console is preferable. Use the console to set configuration data if:
  • You want to override Hiera data. Data set in the console overrides Hiera data when configured as recommended.
  • You want to give someone permission to define or edit data, and they don’t have the skill set to do it in Hiera.
  • You simply prefer the console user interface.
Important: If your installation includes a disaster recovery replica, make sure you enable data editing in the console for both your primary server and replica.
  1. In the console, click Node groups and select the node group that you want to add configuration data to.
  2. On the Configuration data tab, specify a Class and select a Parameter to add.

    You can select from existing classes and parameters in the node group's environment, or you can specify free-form values. Classes aren’t validated, but any class you specify must be present in the node’s catalog at runtime in order for the parameter value to be applied.

    When you select a parameter, the Value field is automatically populated with the inherited or default value.

  3. Optional: If necessary, change the parameter's default Value.

Set parameters

Parameters are declared resource-style, which means you can use them to override other data; however, this override capability can introduce class conflicts and declaration errors that cause Puppet runs to fail.

Important: You can structure parameters as JSON, but, if they can't be parsed as JSON, they're treated as strings.
  1. In the console, click Node groups and select the node group you want to add a parameter to.
  2. On the Classes tab, select the class you want to modify, and select the Parameter you want to add.
    The Parameter list shows all parameters available for the selected class in the node group’s environment. When you select a parameter, the Value field is automatically populated with the inherited or default value.
  3. Optional: If necessary, change the parameter's default Value.

Set variables

Variables you set in the console become top-scope variables available to all Puppet manifests.

Important: You can structure variables as JSON, but, if they can't be parsed as JSON, they're treated as strings.
  1. In the console, click Node groups and select the node group you want to set a variable for.
  2. On the Variables tab, enter the name of the variable in the Key field, and enter the value you want to assign to the variable in the Value field.
  3. Click Add variable and commit changes.

Tips for specifying parameter and variable values

Parameters and variables can be structured as JSON, but, if they can't be parsed as JSON, they're treated as strings.

You can use these data types and syntax to specify parameters and variables:
  • Strings (for example, "centos"): You can use variable-style syntax, which interpolates the result of referencing a fact (for example, "I live at $ipaddress."), or expression-style syntax, which interpolates the result of evaluating the embedded expression (for example, ${$os"release"}).
    Important: Strings must be double-quoted, because single quotes aren't valid JSON.
    Tip: In the console, to provide a value containing a dollar sign that is not part of variable syntax (such as password hashes), you must use a backslash to escape each dollar sign and disable interpolation. For example, the password hash $1$nnkkFwEc$safFMXYaUVfKrDV4FLCm0/ must be escaped as \$1\$nnkkFwEc\$safFMXYaUVfKrDV4FLCm0/.
  • Booleans (for example, true or false).
  • Numbers (for example, 123).
  • Hashes (for example, {"a": 1}).
    Important: You must use colons, not hash rockets.
  • Arrays (for example, ["1","2.3"]).

Variable-style syntax

Variable-style syntax uses a dollar sign ($) followed by a Puppet fact name, such as: "I live at $ipaddress"

Variable-style syntax is interpolated as the value of the fact. For example, $ipaddress resolves to the value of the ipaddress fact.

Restriction: The $pe_node_groups endpoint variable cannot be interpolated when used as a classifier in class variable values.

You can't use indexing in variable-style syntax because the indices are treated as part of the string literal. For example, given the following fact: processors => {"count" => 4, "physicalcount" => 1}, if you use variable-style syntax to specify $processors[count], the value of the processors fact is interpolated and followed by literally [count]. After interpolation, the final value is {"count" => 4,"physicalcount" => 1}[count].

Restriction: Do not use the :: top-level scope indication because the console is not aware of Puppet variable scope.

Expression-style syntax

Use expression-style syntax when you need to index into a fact (such as ${$os[release]}), refer to trusted facts (such as "My name is ${trusted[certname]}"), or delimit fact names from strings (such as "My ${os} release").

For example, this expression-style syntax accesses an operating system's full release number: ${$os"release"}

Expression-style syntax uses theses elements in this order:
  1. An initial dollar sign and curly brace: ${
  2. A legal Puppet fact name preceded by an optional dollar sign.
  3. Any number of index expressions. Quotation marks around indices are optional unless the index string contains spaces or square brackets.
  4. A closing curly brace: }

Indices in expression-style syntax can be used to refer to trusted facts or to access individual fields in structured facts. Use strings in an index to access keys in a hashmap. If you want to access a particular item or character in an array or string based on the order in which it is listed, you can use a zero-indexed integer.

These are examples of legal expression-style interpolation:
  • ${os}
  • ${$os}
  • ${$os[release]}
  • ${$os['release']}
  • ${$os["release"]}
  • ${$os[2]} (Being zero-indexed, this accesses the value of the third key-value pair in the os hash)
  • ${$osrelease} (This accesses the value of the third key-value pair in the release hash)
In the console, an index can be only simple string literals or decimal integer literals. An index cannot include variables or operations (such as string concatenation or integer arithmetic). These are examples of illegal expression-style interpolation:
  • ${$::os}
  • {$os[$release]}
  • ${$os[0xff]}
  • ${$os[6/3]}
  • ${$os[$family + $release]}
  • ${$os + $release}

Trusted facts

Trusted facts are considered to be keys of a hashmap called trusted. This means that trusted facts must be interpolated using expression-style syntax. For example, the certname trusted fact is expressed as "My name is ${trusted[certname]}". Any trusted facts that are themselves structured facts can have further index expressions to access individual fields of that trusted fact.

Restriction: Regular expressions, resource references, and other keywords (such as undef) are not supported.

View nodes in a node group

You can view all nodes that currently match the rules specified for a node group.

  1. In the console, click Node groups and select the node group you want to view.
  2. Click Matching nodes.
Results
The page displays the total number of nodes currently belonging to the group (referred to as matching nodes) and a list of the matching nodes' names.

If you use rules to Dynamically add nodes to a node group, matching nodes are determined by facts collected during the nodes' last Puppet runs, and the matching nodes list is updated when dynamic rules are added, deleted, and edited. Because of How node group inheritance works, nodes must match the rules in ancestor node groups, as well as the rules of the current node group, in order to be appear on the matching nodes list.

If you Statically add nodes to a node group, the pinned nodes belong to the group regardless of other rules.