Revision c54c1493
Added by François ARMAND over 6 years ago
4_advanced_usage/35_directive_ordering.txt | ||
---|---|---|
|
||
Configuration in Rudder are based on desired states, describing the expected state of the system. However, there are cases where having order is desirable (like ensuring that a JVM is present before deploying an Application server, or ensuring a user is present before setting it sudoers), even if it will converge over the course of several agent runs.
|
||
|
||
When policies are generated for each nodes, all Directives based on a same Technique are merged together, preventing a complete ordering of all Directives. However, Rudder uses a best-effort method for ordering Directives, based on alphanumeric ordering.
|
||
In Rudder, there is two separated ways to order things, depending the type of Technique". So, before that, we need to explain how Policies are generated on the
|
||
agent from Directives based on the same Technique.
|
||
|
||
Rudder tries to order first on Rules name, then on Directives name.
|
||
==== Policy generation and Directive merge
|
||
|
||
Example:
|
||
In Rudder, Policies are generated from Directives, but several Directives based on the same Technique always lead to *one* Policy on the agent.
|
||
For unique (non multi-instance) Technique, the one with the highest priority is selected. For multi-instance Technique, the different Directive values are *merged*
|
||
into one Policy after having been sorted.
|
||
|
||
.Separated Policy Generation in Rudder 4.3
|
||
[TIP]
|
||
=====
|
||
In Rudder 4.3, that limitation is lifted and Technique can be made to generate ONE Policy for each Directive. That capacity is controled by the
|
||
`POLICYGENERATION` tag, where the value `merged` is the pre-4.3 default behavior, and values `separated` or `separated-with-param` lead to one Policy per Directive.
|
||
|
||
See https://www.rudder-project.org/redmine/issues/10625[Don't merge directive from same technique on generation] for more information.
|
||
=====
|
||
|
||
|
||
==== Sorting Directives based on the *same* Technique
|
||
|
||
For Directive based on the same Technique, the sort order is based on the *Priority* value of the Directive. Between two Directive, the one with the highest *Priority*
|
||
is the first:
|
||
|
||
- for a *non* multi-instance Technique, it means that it is there is only one that is chosen in the resulting Policies (the others are discared),
|
||
- for a multi-instance Technique, it means that the variables in the Policy will be declared and check in sorting order of Directives (so the first Directive's
|
||
variables will be declared in first position and check first during an agent run).
|
||
|
||
If several *Directives* have the same *Priority*, the *Rule name*, and then the *Directive name* are used for sorting in alphanumeric order.
|
||
|
||
.Priority field value and meaning
|
||
[WARNING]
|
||
======
|
||
The *Priority* field of a Directive used to be a number, from 0 to 10, where 0 means "highest priority".
|
||
This changed with https://www.rudder-project.org/redmine/issues/11725 but if you knew Rudder before that change, please
|
||
use "0" whenever the documentation says "highest priority".
|
||
======
|
||
|
||
|
||
===== Special use case: overriding generic_variable_definition
|
||
|
||
You can use the merging of Directive to define variable override with the "Generic Variable Definition" Technique.
|
||
|
||
For example, let say you want to define a *DNS* variable with default value *[default dns]* and on some node case,
|
||
a value *[overrided dns]*:
|
||
|
||
- Create a Directive [1] with *high* priority: it will be your *default* case, so set *DNS* to *[default dns]*.
|
||
- Create an other Directive [2] with *lower* priority: it will be you specialized case, so set *DNS* to *[overrided dns]*.
|
||
|
||
Then, a node with only Directive [1] will have the default value defined, and a node with both Directives will have the overriding one.
|
||
|
||
It works because on the agent, you can redeclare a variable name and reassign to it a new value: the last one wins (so in our case, the *less* prioritary).
|
||
|
||
|
||
==== Sorting Policies
|
||
|
||
Rudder uses a best-effort method for ordering Policies, based on alphanumeric ordering of the corresponding Rule, then Directive name.
|
||
|
||
When several Directive were merged, Rudder choose the first (Rule name, Directive name) as the ordering value to use for the resulting Policy.
|
||
|
||
|
||
.Best practice
|
||
[TIP]
|
||
=====
|
||
You should always start Rules and Directives name by 2 (or 3) digits to be able to easily reorder Policy evaluation if the need happen:
|
||
|
||
Do not use: "My general security rule" and "Check ssh configuration"
|
||
|
||
But use: "05. My general security rule" and "40. Check ssh configuration"
|
||
=====
|
||
|
||
==== Example
|
||
|
||
- given three Techniques A, B and C
|
||
- directives A1 and A2 based on Technique A, directives B1 and B2 based on B, directives C1 and C2 based on C
|
||
- rule R1 having A1, B1 and C2 and rule R2 having A2, B2 and C2, both applied on a same node,
|
||
- resulting ordering of directive will be: A1, A2, B1, B2, C2, C1
|
||
|
||
Please note that you should avoid configuration that relies on order to be applicable, due to the lack of strict ordering for now.
|
||
- all Directives have the same priority,
|
||
- rule R0 having [C1], R1 having [A1, B2] and rule R2 having [A2, B1, C2], all applied on a same node,
|
||
- merging (R0, C1) and (R2, C2) => [C1, C2] and keep (R0, C1) as Policy order
|
||
- merging (R1, A1) and (R2, A2) => [A1, A2] and keep (R1, A1) as Policy order,
|
||
- merging (R1, B2) and (R2, B1) => [B2, B1] (because R1 < R2) and keep (R1, B2) for policy order,
|
||
- so policies are sort: (R0, C1) then (R1, A1) then (R1, B2)
|
||
- resulting ordering of directive's values will be: [C1, C2] then [A1, A2] then [B1, B2]
|
||
|
Also available in: Unified diff
Fixes #11963: Please, legitimate \"Priority\" usage in multi-instance directives