Project

General

Profile

« Previous | Next » 

Revision c54c1493

Added by François ARMAND over 6 years ago

Fixes #11963: Please, legitimate \"Priority\" usage in multi-instance directives

View differences:

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