Puppet Resource Ordering Options
Over the years Puppet has handled resources ordering without explicit dependencies in different ways, with the release of Puppet 3.3.0 they’ve exposed this ordering logic to the admin with three interesting options.
To test these options out we’ll use the ‘ordering’ test module shown below. We include three classes, ordering::beta, ordering::alpha and ordering::gamma (note that the includes are not in alphabetically sorted order). Each of these classes has three notify statements that show a number and the class they are contained in.
$ find
./modules
./modules/ordering
./modules/ordering/manifests
./modules/ordering/manifests/init.pp
./modules/ordering/manifests/alpha.pp
./modules/ordering/manifests/beta.pp
./modules/ordering/manifests/gamma.pp
$ find -type f | xargs -n 1 cat
class ordering {
include ordering::beta
include ordering::alpha
include ordering::gamma
}
class ordering::alpha {
notify { "Hello number 1 from ordering::alpha": }
notify { "Hello number 2 from ordering::alpha": }
notify { "Hello number 3 from ordering::alpha": }
}
class ordering::beta {
notify { "Hello number 1 from ordering::beta": }
notify { "Hello number 2 from ordering::beta": }
notify { "Hello number 3 from ordering::beta": }
}
class ordering::gamma {
notify { "Hello number 1 from ordering::gamma": }
notify { "Hello number 2 from ordering::gamma": }
notify { "Hello number 3 from ordering::gamma": }
}
First we’ll try the default option - title-hash
. This randomly
orders resources, but will be consistent across runs and nodes. We’ll do
two runs of each option to see if anything changes.
puppet apply --modulepath modules -e 'include ordering' --ordering title-hash | grep -v Stage
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 1 from ordering::beta
Notice: Hello number 2 from ordering::beta
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 3 from ordering::gamma
Notice: Hello number 1 from ordering::gamma
Notice: Hello number 3 from ordering::beta
puppet apply --modulepath modules -e 'include ordering' --ordering title-hash | grep -v Stage
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 1 from ordering::beta
Notice: Hello number 2 from ordering::beta
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 3 from ordering::gamma
Notice: Hello number 1 from ordering::gamma
Notice: Hello number 3 from ordering::beta
This confirms that the ordering is consistent between runs. It
starts off predictably with ordering::alpha running first but note the
ordering::beta at the end, and the difference in ordering of the
notify
s within each class. Hopefully you can see that it’s
not an ordering you should rely upon within your own classes or assume
you can predict.
Now we’ll look at the manifest
value, or ‘chef mode’ as
I’ve heard it nicknamed. This option will cause the resources to be
actioned in in exactly the order you’ve written.
puppet apply --modulepath modules -e 'include ordering' --ordering manifest | grep -v Stage
Notice: Hello number 1 from ordering::beta
Notice: Hello number 2 from ordering::beta
Notice: Hello number 3 from ordering::beta
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 1 from ordering::gamma
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 3 from ordering::gamma
puppet apply --modulepath modules -e 'include ordering' --ordering manifest | grep -v Stage
Notice: Hello number 1 from ordering::beta
Notice: Hello number 2 from ordering::beta
Notice: Hello number 3 from ordering::beta
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 1 from ordering::gamma
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 3 from ordering::gamma
I’ve spaced the output slightly you can see that the order is consistent between runs and grouped in order, by class. Looking at the notify output you can see it’s been produced exactly as we wrote the classes.
The third and final option is my personal favourite and something I’ve
already enabled on some of my dev puppet masters. Setting the ordering
to random
does exactly what the name implies, it orders
resources, including includes!, randomly within a single run and across
multiple runs.
puppet apply --modulepath modules -e 'include ordering' --ordering random | grep -v Stage
Notice: Hello number 3 from ordering::gamma
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 2 from ordering::beta
Notice: Hello number 3 from ordering::beta
Notice: Hello number 1 from ordering::beta
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 1 from ordering::gamma
puppet apply --modulepath modules -e 'include ordering' --ordering random | grep -v Stage
Notice: Hello number 1 from ordering::beta
Notice: Hello number 1 from ordering::alpha
Notice: Hello number 2 from ordering::beta
Notice: Hello number 3 from ordering::beta
Notice: Hello number 3 from ordering::alpha
Notice: Hello number 2 from ordering::alpha
Notice: Hello number 2 from ordering::gamma
Notice: Hello number 1 from ordering::gamma
Notice: Hello number 3 from ordering::gamma
This is a great way to find implicit relationships that have accidentally slipped in to modules before they become real problems. I’d recommend having development hosts and CI boxes running under random to help keep your code explicit and honest.
As a reminder these options -DO NOT- change explicit relationships in
your classes and modules. If explicit ordering is required for your
resources, and especially if you upload the modules to the
puppetforge or github where you have no visibility of peoples puppet
settings, you should continue to use requires / notify / before / after
metaparameters even if you set ordering to manifest
.