Pulling Strings With Puppet - James Turnbull [25]
Here we've executed the fatter binary, which usually returns a full list of the facts available about that node. We've grep'ed for the fact called fqdn (fully qualified domain name) and discovered it is nodel.testing.com. When Puppet created our certificate, it used this value as the hostname used to identify the client to the master.
When connecting, the Puppet client presents this value to the master. The master checks to see whether it matches a node definition. If the fully qualified domain name of the node doesn't match a node definition, it then tries the short name of the host. If the short name of the host doesn't match any node definitions, it looks for a node called default. The default node is a special definition you can create to hold configuration that should apply to all nodes. Lastly, if no node definition matches and the default node isn't defined, the master will return an error indicating that no matching node has been found:
In the error message, you can see the master has indicated that no node called nodel.testing.com or nodes is defined on the master.
So how is a node defined? You can see three nodes defined in Listing 3-15.
In Listing 3-15, we've added some nodes. Each node is identified by the node keyword followed by the name of the node and the configuration defined for that node, enclosed in curly braces.
Tip - As discussed, nodes can be identified by their short name or by their fully qualified domain name. If you specify the fully qualified domain name, you should enclose your node name in single quotes to ensure it is parsed correctly.
Inside your node definition, you can add resources, classes, and definitions. Classes are added using the include function. In webserver.testing.com in Listing 3-15, we've included the apache class. When webserver.testing.com connects, the apache class will be applied to the node to configure it. You can include multiple classes with a single include function by separating them with commas.
In webserver2.testing.com, we've also added a definition, new_vhost, which is qualified as being contained in the virtuals class. Rather than being added using the include function, definitions are specified by name, together with any required parameters.
Node Inheritance
Nodes, like classes, can also inherit the contents of other nodes. In the second node, webserver2.testing.com, in Listing 3-15, we've defined inheritance. In the example, webserver2.testing.com would inherit the properties of webserver.testing.com, meaning that the node would apply the mysgl and rails classes as well as the apache class from nodes. Inheritance is cumulative; we could define a third node that inherits webserver2.testing.com, and the apache, mysql, and rails classes would all be applied to it.
Nodes can only inherit one other node, rather than multiple nodes, using the inherit statement. But you can build a node inheritance model that allows you to group your nodes and apply appropriate configuration to them. This model allows you to assign configuration to nodes via inheritance rather than having to assign it individually to every node.
Note -* Using the include function, you can also include the contents of other nodes in the current node. This does allow you to inherit the contents of multiple nodes.
For example, node inheritance is often used to define a base node that contains your default configuration for all nodes and have that node inherited by all others. But a more complex model can also be created: a base node, inherited by a series of other nodes that are in turn inherited by a succeeding layer of nodes, each layer becoming more granular than the last. You can see this sort of inheritance model in Listing 3-16.
Listing 3-16 shows the definition of a basenode, which includes two classes. We then create four more