Language: Run stages

Included in Puppet Enterprise 2017.1.

Run stages are an additional way to order resources. They allow groups of classes to run before or after nearly everything else, without having to explicitly create relationships with every other class.

Run stages have several major limitations; you should understand these before attempting to use them.

The run stage feature has two parts:

  • A stage resource type.
  • A stage metaparameter, which assigns a class to a named run stage.

The default main stage

By default there is only one stage (named “main”). All resources are automatically associated with this stage unless explicitly assigned to a different one. If you do not use run stages, every resource is in the main stage.

Custom stages

Additional stages are declared as normal resources. Each additional stage must have an order relationship with another stage, such as Stage['main']. As with normal resources, these relationships can be specified with metaparameters or with chaining arrows.

stage { 'first':
  before => Stage['main'],
stage { 'last': }
Stage['main'] -> Stage['last']

In the above example, all classes assigned to the first stage will be applied before the classes associated with the main stage and both stages will be applied before the last stage.

Assigning classes to stages

Once stages have been declared, a class can be assigned to a custom stage with the stage metaparameter.

class { 'apt-keys':
  stage => first,

The above example will ensure that the apt-keys class happens before all other classes, which can be useful if most of your package resources rely on those keys.

Limitations and known issues

  • In order to assign a class to a stage, you must use the resource-like class declaration syntax and supply the stage explicitly. You cannot assign classes to stages with the include function, or by relying on automatic parameter lookup from hiera while using resource-like class declarations.
  • You cannot subscribe to or notify resources across a stage boundary.
  • Classes that contain other classes (with either the contain function or the anchor pattern) can sometimes behave badly if declared with a run stage — if the contained class is only declared by its container, it will work fine, but if it is also declared anywhere outside its container, it will often create a dependency cycle that will prevent the involved classes from being applied.

Due to these limitations, stages should only be used with the simplest of classes, and only when absolutely necessary. Mass dependencies like package repositories are effectively the only valid use case.

↑ Back to top