When configuring a node, Puppet agent uses a document called a catalog, which it downloads from a Puppet master server. The catalog describes the desired state for each resource that should be managed, and can specify dependency information for resources that should be managed in a certain order.
Puppet manifests are concise because they can express variation between nodes with conditional logic, templates, and functions. By resolving these on the master and giving the agent just a specific catalog, Puppet is able to:
Puppet apply compiles its own catalog and then applies it, so it plays the role of both Puppet master and Puppet agent.
Puppet compiles a catalog using three main sources of configuration info:
All of these sources are used by both agent/master deployments and by stand-alone Puppet apply nodes.
When agents request a catalog, they send four pieces of information to the Puppet master:
/puppet/v3/catalog/web01.example.com?environment=production) This is almost always the same as the certname.
/puppet/v3/catalog/web01.example.com?environment=production) Before requesting a catalog, agents will ask the master which environment they should be in, but they will use the environment in their own config file if the master doesn’t have an opinion.
Puppet can use external data at several stages when compiling, but there are two main kinds to be aware of:
This is the heart of a Puppet deployment. It can include:
.ppfiles for easier organization
This description is simplified. It doesn’t delve into the internals of the parser, model, evaluator, etc., and some items are presented out of order for the sake of conceptual clarity.
For practical purposes, you can treat Puppet apply nodes as simply a combined agent and master.
This process begins after the catalog request has been received.
Once the Puppet master has the agent-provided information for this request, it asks its configured node terminus for a node object.
By default, Puppet master uses the
plain node terminus, which just returns a blank node object. This results in only manifests and agent-provided info being used in compilation.
The next most common node terminus is the
exec node terminus, which will request data from an external node classifier (ENC). This can return classes, variables, and/or an environment, depending on how the ENC is designed.
Finally, it’s possible to write a custom node terminus that retrieves classes, variables, and environments from any kind of external system.
$factshash, and certain data from the node’s certificate will be set in the protected
$trustedhash. See the page on facts and built-in variables for more details.
All of these variables will be available for use by any manifest or template during the subsequent stages of compilation.
The main manifest can contain any arbitrary Puppet code. The way it is evaluated is:
If any classes were declared in the main manifest and their definitions were not present, Puppet will automatically load the manifests containing them from its collection of modules. It will follow the normal manifest naming conventions to locate the files it should load.
Once a class is loaded, the Puppet code in it is evaluated, and any resources are added to the catalog. If it was declared at node scope, it has access to any node-scope variables; otherwise, it only has access to top-scope variables.
Classes can also declare other classes; if they do, Puppet will load and evaluate those in the same way.
Finally, after Puppet has evaluated the main manifest and any classes it declared (and any classes they declared), it will load from modules and evaluate any classes that were specified by the node object. Resources from those classes will be added to the catalog.
If a matching node definition was found in step 3, these classes are evaluated at node scope, which means they can access any node-scope variables set by the main manifest. If no node definitions were present in the main manifest, they will be evaluated at top scope.