Skip to content

Instantly share code, notes, and snippets.

@Sharpie
Last active September 16, 2020 16:13
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Sharpie/870b331df300b29d7d406c49bb656db5 to your computer and use it in GitHub Desktop.
Save Sharpie/870b331df300b29d7d406c49bb656db5 to your computer and use it in GitHub Desktop.
How Environments Happen: In Puppet 5.3
    __  __                 ______           _                                       __
   / / / /___ _      __   / ____/___ _   __(_)________  ____  ____ ___  ___  ____  / /______
  / /_/ / __ \ | /| / /  / __/ / __ \ | / / / ___/ __ \/ __ \/ __ `__ \/ _ \/ __ \/ __/ ___/
 / __  / /_/ / |/ |/ /  / /___/ / / / |/ / / /  / /_/ / / / / / / / / /  __/ / / / /_(__  )
/_/ /_/\____/|__/|__/  /_____/_/ /_/|___/_/_/   \____/_/ /_/_/ /_/ /_/\___/_/ /_/\__/____/

    __  __                             __
   / / / /___ _____  ____  ___  ____  / /
  / /_/ / __ `/ __ \/ __ \/ _ \/ __ \/ /
 / __  / /_/ / /_/ / /_/ /  __/ / / /_/
/_/ /_/\__,_/ .___/ .___/\___/_/ /_(_)
═══════════/_/═══/_/═══════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                             │
│ In Puppet 5.3                                                                               │
│                                                                                             │
└─────────────────────────────────────────────────────────────────────────────────────────────┘
               ┌─────────────┐                              ┌─────────────┐      ┌───────────────┐
               │Puppet Agent │                              │Puppet Server│      │Node Classifier│
               └─────────────┘                              └─────────────┘      └───────────────┘
                      ┃                                            ┃                     ┃
              ┌────────────────┐
              │server_list set?│ ┌───┐                             ┃                     ┃
              │  (HA enabled)  ├─┤Yes├──────┐
              └───┬───┳────────┘ └───┘      │                      ┃                     ┃
                ┌─┴┐                        │
                │No│  ┃                     │                      ┃                     ┃
                └─┬┘                        │
        ┌───┐ ┌───┴───┻───────────┐         │                      ┃                     ┃
      ┌ ┤Yes├ ┤node_name_fact set?│         │
        └───┘ └───┬───┳───────────┘         │                      ┃                     ┃
      │         ┌─┴┐                        │
                │No│  ┃                     │                      ┃                     ┃
      │         └─┬┘                        │
┌ ─ ─ ─ ─ ─       │   ┃                     │                      ┃                     ┃
 Pluginsync├ ─ ─ ─◎                         │
└ ─ ─ ─ ─ ─       │   ┃                     │                      ┃                     ┃
                  │                         │
        ┌───┐ ┌───┴───┻────────────────────┐│                      ┃                     ┃
      ┌─┤Yes├─┤strict_environment_mode set?││
      │ └───┘ └───┬───┳────────────────────┘│                      ┃                     ┃
      │         ┌─┴┐                        │
      │         │No│  ┃                     │                      ┃                     ┃
      │         └─┬┘                        │   ┌───┐      ┌────────────────┐
      │           └───╋─────────────────────┴───┤GET├─────▶│/puppet/v3/node │◀═══════════▶
      │                                         └───┘      └──┬─────────────┘       ▲
      │       ┌───────┻─────────────────────┐                 │    ┃                │    ┃
      │       │   Switch Env If necessary   │◀────────────────┘                     │
      │       └───┬───┳─────────────────────┘                      ┃                │    ┃
      │           │                                                                 │
      │           │   ┃                                            ┃                │    ┃
      │       ┌───┴─────────────────────────┐              ┌──────────────┐         │
      └───────┤                             │◀════════════▶│ File Server  │         │    ┃
              │         Pluginsync          │◀════════════▶│     API      │         │
      ┌───────┤                             │◀════════════▶│  Endpoints   │         │    ┃
      │       └───┬─────────────────────────┘              └──────────────┘         │
      │           │   ┃                                            ┃                │    ┃
      │           │                                              ┌───────────┐      │
      │           │   ┃                                       ┌─▶│YAML Cache │──────┤    ┃
      │       ┌───┴───────┐                                   │  ├───────────┤
      │       │Load Facts │                                   ├─▶│ PuppetDB  │─ ─ ─ ┘    ┃
      │       └───┬───────┘                                   │  └───────────┘
      │           │   ┃                                       │    ┃                     ┃
      │           │                                           │
      │       ┌───┴───┻─────────────────────┐  ┌────┐      ┌──┴────┻──────────┐          ┃
      │       │       Request Catalog       │──┤POST├─────▶│/puppet/v3/catalog│◀═════════▶
┌─────┴────┐  └───────┳─────────────────────┘  └────┘      └──┬───────────────┘
│    No    │                                                  │
│ (Loop up │  ┌───────┻─────────────────────┐                 │
│  to 3x)  ├──┤Catalog Environment Matches? │◀────────────────┘
└──────────┘  └───┬───┳─────────────────────┘
                  │
                ┌─┴─┐ ┃
                │Yes│
                └─┬─┘ ┃
                  │
              ╔═══╩═══╩═════════════════════╗
              ║        Apply Catalog        ║
              ╚═════════════════════════════╝

All puppet agent runs start out in the Puppet::Configurer#run method which is invoked by the puppet daemon and puppet agent -t, or puppet apply. The workflows used by puppet apply and puppet agents that are configured to use cached catalogs don't check environments against a Puppet Server, so the remainder of this document will focus on the workflow of an agent retrieving and enforcing a freshly compiled catalog.

The first thing an agent run does is to determine the environment to use for pluginsync. This is done by an GET call to the /puppet/v3/node API endpoint of the Puppet Server. Notably, this API endpoint does not accept a data payload, which means no facts can be submitted. However, the API request will include the agent's certificate, which means that "trusted" node data is sent. the Puppet Server processing the API request will also load facts from its cache, if available. The Puppet Server cache is pluggable (via routes.yaml) and split into two levels, commonly configured as follows:

  • YAML cache: On-disk storage of the last factset directly submitted by nodes, or fetched from the level 2 cache. This usually contains factsets submitted by nodes as part of a catalog request and therefore contains "normal facts". Factsets fetched from the level 2 cache might have additional data, as noted below.

  • PuppetDB cache: Contains factsets stored in PuppetDB. This is used if the master doesn't have any data in the level 1 cache, or the data in the level 1 cache is expired. Both of these situations occur commonly in pools of compile masters. Notably, the factsets returned by PuppetDB have "trusted" node data merged together with "normal facts", which creates the potential for interesting edge cases if there is a miss in the level 1 cache.

The Puppet Server forwards the node request along with any cached facts to the configured Node Classifier and returns the response of that service to the agent.

If the puppet agent is part of a HA deployment where server_list is set, the initial request to /puppet/v3/nodes will be used to select a healthy server from the list of available options. Otherwise the value of the server setting will be used. The logic branches further in the non-HA case if the node_name_fact setting is also set, with the agent performing a pluginsync prior to the initial node request. This behavior is specific to the non-HA case, and the node_name_fact setting is not commonly used.

If the response to the node request contains a different environment from the one specified by puppet.conf, the agent will switch to that environment if the strict_environment_mode setting is not enabled. The following message will be logged at NOTICE level when the agent switches environments due to a node response:

Notice: Local environment: 'production' doesn't match server specified node environment '<node request env>', switching agent to '<node request env>'.

The agent then performs a pluginsync against the currently active environment and loads facts. These facts are submitted as the data payload of a POST call to the [/puppet/v3/catalog API endpoint][catalog-api] of the Puppet Server. The Puppet Server uses these facts to refresh both the level 1 and level 2 caches and then performs another node request to the configured Node Classifier service and compiles a catalog for the agent using the environment returned by the Classifer. The compiled catalog is returned to the agent.

The agent compares the environment of the catalog the Puppet Server returned against its currently active environment. If they differ and the strict_environment_mode setting is enabled, then the run is failed. Otherwise, if the environments differ, the agent switches its active environment and logs the following message at NOTICE level:

Notice: Local environment: 'production' doesn't match server specified environment '<catalog env>', restarting agent run with environment '<catalog env>'

When switching environments at this stage, the agent returns to pluginsync, reloads facts, and issues a new POST request to the /puppet/v3/catalog API. If the agent receives a catalog that matches its active environment, then it will continue on to the application phase of its run. Otherwise, it will retry up to three times before the run is failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment