Chaining arrows

You can create relationships between resources or groups of resources using the -> and ~> operators.

The ordering arrow is a hyphen and a greater-than sign (->). It applies the resource on the left before the resource on the right.

The notifying arrow is a tilde and a greater-than sign (~>). It applies the resource on the left first. If the left-hand resource changes, the right-hand resource refreshes.

In this example, Puppet applies configuration to the ntp.conf file resource and notifies the ntpd service resource if there are any changes.

File['/etc/ntp.conf'] ~> Service['ntpd']

When possible, use relationship metaparameters, not chaining arrows. Metaparameters are more explicit and easier to maintain. See the Puppet language style guide for information on when and how to use chaining arrows.

Operands

The chaining arrows accept the following kinds of operands on either side of the arrow:

  • Resource references, including multi-resource references.
  • Arrays of resource references.
  • Resource declarations.

  • Resource collectors.

You can link operands to apply a series of relationships and notifications. In this example, Puppet applies configuration to the package, notifies the file resource if there are changes, and then, if there are resulting changes to the file resouce, Puppet notifies the service resource:

Package['ntp'] -> File['/etc/ntp.conf'] ~> Service['ntpd']

Resource declarations can be chained. That means you can use chaining arrows to make Puppet apply a section of code in the order that it is written. This example applies configuration to the package, the file, and the service, in that order, with each related resource notifying the next of any changes:

# first:
package { 'openssh-server':
  ensure => present,
} # and then:
-> file { '/etc/ssh/sshd_config':
  ensure => file,
  mode   => '0600',
  source => 'puppet:///modules/sshd/sshd_config',
} # and then:
~> service { 'sshd':
  ensure => running,
  enable => true,
}

Collectors can also be chained, so you can create relationships between many resources at one time. This example applies all Yum repository resources before applying any package resources, which protects any packages that rely on custom repositorie :

Yumrepo <| |> -> Package <| |>

Capturing resource references for generated resources

In Puppet, the value of a resource declaration is a reference to the resource it creates.

This is useful if you're automatically creating resources whose titles you can't predict: use the iteration functions to declare several resources at once or use an array of strings as a resource title. If you assign the resulting resource references to a variable, you can then use them in chaining statements without ever knowing the final title of the affected resources.

For example:

  • The map function iterates over its arguments and returns an array of values, with each value produced by the last expression in the block. If that last expression is a resource declaration, map produces an array of resource references, which you could then use as an operand for a chaining arrow.
  • For a resource declaration whose title is an array, the value is itself an array of resource references that you can assign to a variable and use in a chaining statement.

Cautions when chaining resource collectors

Chains can create dependency cycles.
Chained collectors can cause huge dependency cycles; be careful when using them. They can also be dangerous when used with virtual resources, which are implicitly realized by collectors.
Chains can break.
Although you can usually chain many resources or collectors together (File['one'] -> File['two'] -> File['three']), the chain can break if it includes a collector whose search expression doesn't match any resources.
Implicit properties aren't searchable.
Collectors can search only on attributes present in the manifests; they cannot see properties that are automatically set or are read from the target system. For example, the chain Yumrepo <| |> -> Package <| provider == yum |>, creates only relationships with packages whose provider attribute is explicitly set to yum in the manifests. It would not affect packages that didn't specify a provider but use Yum because it's the operating system's default provider.

Reversed forms

Both chaining arrows have a reversed form (<- and <~). As implied by their shape, these forms operate in reverse, causing the resource on their right to be applied before the resource on their left. Avoid these reversed forms, as they are confusing and difficult to notice.