About environments

An environment is an isolated group of agent nodes that a primary server can serve with its own main manifest and set of modules. For example, you can use environments to set up scratch nodes for testing before rolling out changes to production, or to divide a site by types of hardware.

Related topics: main manifests, module paths.

Look up which environment a node is in

If you need to determine which environment a certain node is part of, look it up using the puppet node find command.

To look up which environment a node is in, run puppet node find <node> on the Puppet Server host node, replacing <node> with the node's exact name.
Alternatively, run puppet node find <node> --render_as json | jq .environment to render the output as JSON and return only the environment name.
Note: The node name must exactly match the name in the node's certificate, including capitalization. By default, a node's name is its fully qualified domain name, but the node's name can be changed by using the certname and node_name_value settings on the node itself.

Access environment name in manifests

If you want to share code across environments, use the $environment variable in your manifests.

To get the name of the current environment:

  1. Use the $environment variable, which is set by the primary server.

Environment scenarios

The main uses for environments fall into three categories: permanent test environments, temporary test environments, and divided infrastructure.

Permanent test environments

In a permanent test environment, there is a stable group of test nodes where all changes must succeed before they can be merged into the production code. The test nodes are a smaller version of the whole production infrastructure. They are either short-lived cloud instances or longer-lived virtual machines (VMs) in a private cloud. These nodes stay in the test environment for their whole lifespan.

Temporary test environments

In a temporary test environment, you can test a single change or group of changes by checking the changes out of version control into the $codedir/environments directory, where it is detected as a new environment. A temporary test environment can either have a descriptive name or use the commit ID from the version that it is based on. Temporary environments are good for testing individual changes, especially if you need to iterate quickly while developing them. When you’re done with a temporary environment, you can delete it. The nodes in a temporary environment are short-lived cloud instances or VMs, which are destroyed when the environment ends.

Divided infrastructure

If parts of your infrastructure are managed by different teams that do not need to coordinate their code, you can split them into environments.

Environments limitations

Environments have limitations, including leakage and conflicts with exported resources.

Plugins can leak between environments

Environment leakage occurs when different versions of Ruby files, such as resource types, exist in multiple environments. When these files are loaded on the primary server, the first version loaded is treated as global. Subsequent requests in other environments get that first loaded version. Environment leakage does not affect the agent, as agents are only in one environment at any given time. For more information, see below for troubleshooting environment leakage.

Exported resources can conflict or cross over

Nodes in one environment can collect resources that were exported from another environment, which causes problems — either a compilation error due to identically titled resources, or creation and management of unintended resources. The solution is to run separate primary servers for each environment if you use exported resources.

Troubleshoot environment leakage

Environment leakage is one of the limitations of environments.

Use one of the following methods to avoid environmental leakage:
  • For resource types, you can avoid environment leaks with the the puppet generate types command as described in environment isolation documentation. This command generates resource type metadata files to ensure that each environment uses the right version of each type.

  • This issue occurs only with the Puppet::Parser::Functions API. To fix this, rewrite functions with the modern functions API, which is not affected by environment leakage. You can include helper code in the function definition, but if helper code is more complex, package it as a gem and install for all environments.

  • Report processors and indirector termini are still affected by this problem, so put them in your global Ruby directories rather than in your environments. If they are in your environments, you must ensure they all have the same content.