Search code examples
puppet

What is the difference between Relationship Metaparameters vs Chaining Arrows?


The Puppet Language Relationships page has Relationship Metaparameters (before, require, notify, subscribe) and Chaining Arrows (->, ~>).

It seems that these could be used to the same effect. Using the examples they give, you could use before or require to dictate the order or it seems that you could also state Package['openssh-server'] -> File['/etc/ssh/sshd_config'].

What's the difference between these options?

What is considered "best practice" for ordering?

Also, when is it better to use before (or notify) vs require (or subscribe)? Does it matter or is it just a matter of preference?

same ordering relationship
package { 'openssh-server':
  ensure => present,
  before => File['/etc/ssh/sshd_config'],
}
file { '/etc/ssh/sshd_config':
  ensure  => file,
  mode    => 600,
  source  => 'puppet:///modules/sshd/sshd_config',
  require => Package['openssh-server'],
}

same notification relationship:
file { '/etc/ssh/sshd_config':
  ensure => file,
  mode   => 600,
  source => 'puppet:///modules/sshd/sshd_config',
  notify => Service['sshd'],
}
service { 'sshd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ssh/sshd_config'],
}

Solution

  • Yes, the relationship metaparameters and the chaining operators are different means to achieve the same ends. The metaparameters have been in Puppet longer.

    The chaining operators are distinguished by the fact that they can be used outside the scope of resource declarations without overriding resource parameters (overrides are not always possible). They are especially useful in conjunction with resource collectors, so for example:

    Group<||> -> User<||>
    

    The metaparameters are distinguished by being parameters. Among other things, that means their values can be drawn from resource defaults and / or from variables or class parameters.

    There is no consensus best practice for whether to prefer chaining arrows or metaparameters for the many cases where both are viable. I personally tend to prefer metaparameters when the relationship seems inherent in the nature of one or both resources, which is a lot of the time.

    As to before/notify vs. require/subscribe, you will find that in many cases, it is more natural to define the relationship on one side than on the other. This is especially true when one of the related resources is declared only conditionally: you then need to declare the relationship on the conditional side, lest the unconditional side sometimes have an unresolved relationship. It can also be true when many resources must be related to one: even if you know all the resources involved, it is often easier to declare the relationship on the "many" side.

    In many cases, however, yes, it is a matter of preference.