Creating environments

An environment is a branch that gets turned into a directory on your primary Puppet server. Environments are turned on by default.

Environment structure

The structure of an environment follows several conventions.

When you create an environment, you give it the following structure:

  • It contains a modules directory, which becomes part of the environment’s default module path.

  • It contains a manifests directory, which is the environment’s default main manifest.

  • If you are using Puppet 5, it can optionally contain a hiera.yaml file.

  • It can optionally contain an environment.conf file, which can locally override configuration settings, including modulepath and manifest.

    Note: Environment names can contain lowercase letters, numbers, and underscores. They must match the following regular expression rule: \A[a-z0-9_]+\Z. If you are using Puppet 5, remove the environment_data_provider setting.

Environment resources

An environment specifies resources that the primary server uses when compiling catalogs for agent nodes. The modulepath, the main manifest, Hiera data, and the config version script, can all be specified in environment.conf.

The modulepath

The modulepath is the list of directories Puppet loads modules from. By default, Puppet loads modules first from the environment’s directory, and second from the primary server's puppet.conf file’s basemodulepath setting, which can be multiple directories. If the modules directory is empty or absent, Puppet only uses modules from directories in the basemodulepath.

Related topics: module path.

The main manifest

The main manifest is the starting point for compiling a catalog. Unless you say otherwise in environment.conf, an environment uses the global default_manifest setting to determine its main manifest. The value of this setting can be an absolute path to a manifest that all environments share, or a relative path to a file or directory inside each environment.

The default value of default_manifest is ./manifests — the environment’s own manifests directory. If the file or directory specified by default_manifest is empty or absent, Puppet does not fall back to any other manifest. Instead, it behaves as if it is using a blank main manifest. If you specify a value for this setting, the global manifest setting from puppet.conf is not be used by an environment.

Related topics: main manifest, environment.conf, default_manifest setting, puppet.conf.

Hiera data

Each environment can use its own Hiera hierarchy and provide its own data.

Related topics: Hiera config file syntax.

The config version script

Puppet automatically adds a config version to every catalog it compiles, as well as to messages in reports. The version is an arbitrary piece of data that can be used to identify catalogs and events. By default, the config version is the time at which the catalog was compiled (as the number of seconds since January 1, 1970).

The environment.conf file

An environment can contain an environment.conf file, which can override values for certain settings.

The environment.conf file overrides these settings:

  • modulepath
  • manifest
  • config_version
  • environment_timeout

Related topics: environment.conf

Create an environment

Create an environment by adding a new directory of configuration data.

  1. Inside your code directory, create a directory called environments.
  2. Inside the environments directory, create a directory with the same name as your new environment.
  3. Inside that directory, create a modules directory and a manifests directory. These two directories contain your Puppet code.
  4. Configure a modulepath:
    1. Set modulepath in its environment.conf file . If you set a value for this setting, the global modulepath setting from puppet.conf is not used by an environment.
    2. Check the modulepath by specifying the environment when requesting the setting value:
    $ sudo puppet config print modulepath --section server --environment test /etc/puppetlabs/code/environments/test/modules:/etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules.
    Note: In Puppet Enterprise (PE), every environment must include /opt/puppetlabs/puppet/modules in its modulepath, because PE uses modules in that directory to configure its own infrastructure.
  5. Configure a main manifest:
    1. Set manifest in its environment.conf file. As with the global default_manifest setting, you can specify a relative path (to be resolved within the environment’s directory) or an absolute path.
    2. Lock all environments to a single global manifest with the disable_per_environment_manifest setting — preventing any environment setting its own main manifest.
  6. To specify an executable script that determines an environment’s config version:
    1. Specify a path to the script in the config_version setting in its environment.conf file. Puppet runs this script when compiling a catalog for a node in the environment, and uses its output as the config version. If you specify a value here, the global config_version setting from puppet.conf is not used by an environment.
    Note: If you’re using a system binary like git rev-parse, specify the absolute path to it. If config_version is set to a relative path, Puppet looks for the binary in the environment, not in the system’s PATH.
Results
Example environment.conf file:
# /etc/puppetlabs/code/environments/test/environment.conf

# Puppet Enterprise requires $basemodulepath; see note below under "modulepath".
modulepath = site:dist:modules:$basemodulepath

# Use our custom script to get a git commit for the current state of the code:
config_version = get_environment_commit.sh

Related topics: Deploying environments with r10k, Code Manager control repositories, disable_per_environment_manifest

Assign nodes to environments via an ENC

You can assign agent nodes to environments by using an external node classifier (ENC). By default, all nodes are assigned to a default environment named production.

The interface to set the environment for a node is different for each ENC. Some ENCs cannot manage environments. When writing an ENC:

  1. Ensure that the environment key is set in the YAML output that the ENC returns. If the environment key isn’t set in the ENC’s YAML output, the primary server uses the environment requested by the agent.
Note: The value from the ENC is authoritative, if it exists. If the ENC doesn’t specify an environment, the node’s config value is used.
Related topics: writing ENCs.

Assign nodes to environments via the agent's config file

You can assign agent nodes to environments by using the agent’s config file. By default, all nodes are assigned to a default environment named production.

To configure an agent to use an environment:

  1. Open the agent's puppet.conf file in an editor.
  2. Find the environment setting in either the agent or main section.
  3. Set the value of the environment setting to the name of the environment you want the agent to be assigned to.
Results

When that node requests a catalog from the primary server, it requests that environment. If you are using an ENC and it specifies an environment for that node, it overrides whatever is in the config file.

Note: Nodes cannot be assigned to unconfigured environments. If a node is assigned to an environment that does not exist — no directory of that name in any of the environment path directories — the primary server fails to compile its catalog. The one exception to this is if the default production environment does not exist. In this case, the agent successfully retrieves an empty catalog.

Global settings for configuring environments

The settings in the primary server's puppet.conf file configure how Puppet finds and uses environments.

environmentpath

The environmentpath setting is the list of directories where Puppet looks for environments. The default value for environmentpath is $codedir/environments. If you have more than one directory, separate them by colons and put them in order of precedence.

In this example, temp_environments is searched before environments:
$codedir/temp_environments:$codedir/environments

If environments with the same name exist in both paths, Puppet uses the first environment with that name that it encounters.

Put the environmentpath setting in the main section of the puppet.conf file.

basemodulepath

The basemodulepath setting lists directories of global modules that all environments can access by default. Some modules can be made available to all environments. The basemodulepath setting configures the global module directories.

By default, it includes $codedir/modules for user-accessible modules and /opt/puppetlabs/puppet/modules for system modules.

Add additional directories containing global modules by setting your own value for basemodulepath.

Related topics: modulepath.

environment_timeout

The environment_timeout setting sets how often the primary server refreshes information about environments. It can be overridden per-environment.

This setting defaults to 0 (caching disabled), which lowers the performance of your primary server but makes it easy for new users to deploy updated Puppet code. After your code deployment process is mature, change this setting to unlimited.

All code in Ruby and Puppet loaded from the environment is cached. Inputs to compilation (for example, facts and looked up values) and the resulting catalog, are not cached.

disable_per_environment_manifest

The disable_per_environment_manifest setting lets you specify that all environments use a shared main manifest.

When disable_per_environment_manifest is set to true, Puppet uses the same global manifest for every environment. If an environment specifies a different manifest in environment.conf, Puppet does not compile catalogs nodes in that environment, to avoid serving catalogs with potentially wrong contents.

If this setting is set to true, the default_manifest value must be an absolute path.

default_manifest

The default_manifest setting specifies the main manifest for any environment that doesn’t set a manifest value in environment.conf. The default value of default_manifest is ./manifests — the environment’s own manifests directory.

The value of this setting can be:

  • An absolute path to one manifest that all environments share.

  • A relative path to a file or directory inside each environment’s directory.

Related topics: default_manifest setting.

Configure the environment timeout setting

The enviroment_timeout setting determines how often the primary Puppet server caches the data it loads from an environment. For best performance, change the settings after you have a mature code deployment process.

  1. Set environment_timeout = unlimited in puppet.conf.
  2. Change your code deployment process to refresh the primary server whenever you deploy updated code. For example, set a postrun command in your r10k config or add a step to your continuous integration job.
    • With Puppet Server, refresh environments by calling the environment-cache API endpoint. Ensure you have write access to the puppet-admin section of the puppetserver.conf file.

    • With a Rack primary server, restart the web server or the application server. Passenger lets you touch a restart.txt file to refresh an application without restarting Apache. See the Passenger docs for details.

Results
The environment-timeout setting can be overridden per-environment in environment.conf.
Note: Only use the value 0 or unlimited. Most primary servers use a pool of Ruby interpreters, which all have their own cache timers. When these timers are out of sync, agents can be served inconsistent catalogs. To avoid that inconsistency, refresh the primary server when deploying.