Run stages

Run stages are an additional way to order resources. Groups of classes run before or after everything else, without having to explicitly create relationships with other classes. The run stage feature has two parts: a stage resource type, and a stage metaparameter, which assigns a class to a named run stage.

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 are specified with metaparameters or with chaining arrows.

In this example, all classes assigned to the first stage are applied before the classes associated with the main stage, and both of those stages are applied before the last stage.
stage { 'first':
  before => Stage['main'],
}
stage { 'last': }
Stage['main'] -> Stage['last']

Assigning classes to stages

After stages have been declared, use the stage metaparameter to assign a class to a custom stage.

This example ensures that the apt-keys class happens before all other classes, which is useful if most of your package resources rely on those keys.
class { 'apt-keys':
  stage => first,
}

Limitations

Run stages have these limitations:
  • 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 declared only by its container, it works fine, but if it's declared anywhere outside its container, it often creates a dependency cycle that prevents the involved classes being applied.
CAUTION: Due to these limitations, use stages with the simplest of classes, and only when absolutely necessary. A valid use case is mass dependencies like package repositories.