Puppet: System Administration Automated

Support

Using Multiple Environments

As of 0.24.0, Puppet has support for multiple environments, along the same lines as Ruby on Rails. The idea behind these environments is to provide an easy mechanism for managing machines at different levels of SLA -- some machines need to be up constantly and thus cannot tolerate disruptions and usually use older software, while other machines are more up to date and are used for testing upgrades to more important machines.

Puppet allows you to define whatever environments you want, but it is recommended that you stick to production, testing, and development for community consistency. Valid environment names need to be defined, both server-side and client-side. This is done via the environments variable defined in ConfigurationReference.

Puppet defaults to not using an environment, and if you do not set one on either the client or server, then it will behave as though environments do not exist at all, so you can safely ignore this feature if you do not need it.

Please note: Not using Environments doesn't mean that client doesn't have an Environment set. The client's environment is per default set to development and will only be changed by changing the clients configuration or per command parameter. You can't set it to a default value on the server side . For a more detailed discussion have a look at: environment default setting - thread on the mailing list.

Possible Goal of Environments

The main goal of a setup split by environments could be that puppet can run different sources (of modules, manifests etc. ) for different environments on the same master. See more here: ConfigurationReference

This enables for example the possibility to have a stable and a testing branch of your manifests and modules and therefor it would be possible to do any development work in a safe testing environment and leave all Production-Servers untouched from the development and its possible damages. To test the new developed Manifest(s), Module(s), etc. one or some Server(s) could be run against the testing environment with the following command:

puppetd --test --environment=development

This is a normal puppetrun from the command line interface with the environment set to development.

Finally the changes could be merged into the production environment and would get ''safely'' applied and nothing should get broken.

CommonModules describes a more technical Implementation of this idea. puppet module testing to production deployment - thread on the mailing list holds the original description of this page.

Setting The Client's Environment

There are two ways to set the client's environment. The easiest is just to put the environment information in the client's puppet.conf file:

[main]
    environment = production

This will inform the server which environment the client is in.

Alternatively, rather than specifying this statically in the configuraton file, you could create a custom fact that set the client environment based upon some other client attribute or an external data source.

The preferred way of setting the environment is to use an external node configuration tool; these tools can directly specify a node's environment and are generally much better at specifying node information than Puppet is.

Additionally, if you are not using the default environment names (production, development), you must also specify the valid environments for the client, in addition to which environment the client is in:

[main]
    environments = production,development,staging

[puppetd]
    environment = staging

This says that the valid environments for this client "production,development,staging" (the default is "production,development"), and the environment the client wants to use is "staging".

Using Environments on the Server

The point of the environment is to choose which manifests, templates, and files are sent to the client. Thus, Puppet must be configured to provide environment-specific sources for this information. The environment is also available as $environment within your manifests, so you can use the same manifests everywhere and behave differently internally depending on the environment.

Puppet environments are implemented rather simply: You add per-environment sections to the server's configuration file, choosing different configuration sources for each environment. These per-environment sections are then used in preference to the main sections. For instance:

[main]
    modulepath = /usr/share/puppet/modules

[development]
    modulepath = /usr/share/puppet/development/modules

In this case, any clients in the development environment will have its modules searched for in the separate development tree, while any other environment will fall through to the main configuration section. Puppet configurations use a simple search path for picking which value to use:

  • Values specified on the command line
  • Values specified in an environment-specific section
  • Values specified in an executable-specific section
  • Values specified in the main section

Only certain parameters make sense to be configured per-environment, and all of those parameters revolve around specifying what files to use to compile a client's configuration. Those parameters are:

  • modulepath: Where to look for modules. It's best to have a standard module directory that all environments share and then a per-environment directory where custom modules can be stored.
  • templatedir: Where to look for templates. The modulepath should be preferred to this setting, but it allows you to have different versions of a given template in each environment.
  • manifest: Which file to use as the main entry point for the configuration. The Puppet parser looks for other files to compile in the same directory as this manifest, so this parameter also determines where other per-environment Puppet manifests should be stored. With a separate module path, it should be easy to use the same simple manifest in all environments.

Additionally, the file server uses an environment-specific module path; if you do your file serving from modules, instead of separately mounted directories, your clients will be able to get environment-specific files.

Environments and Modules

Note that using multiple environments works much better if you rely largely on modules, and you'll find it easier to migrate changes between environments by encapsulating related files into a module. It is recommended that you switch as much as possible to modules if you plan on using environments.