From 48da0597c0888a13bcc9adf431ac05643a9ba9bb Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 6 Sep 2017 23:36:01 -0400 Subject: [PATCH] document ansible_group_priority (#28777) * document ansible_group_priority * Copy edit pass --- docs/docsite/rst/intro_inventory.rst | 30 +++++++++++++++++++++++- docs/docsite/rst/playbooks_variables.rst | 4 +++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/docsite/rst/intro_inventory.rst b/docs/docsite/rst/intro_inventory.rst index e42927f052..4632504ab3 100644 --- a/docs/docsite/rst/intro_inventory.rst +++ b/docs/docsite/rst/intro_inventory.rst @@ -222,12 +222,40 @@ directory will override variables set in the inventory directory. Tip: Keeping your inventory file and variables in a git repo (or other version control) is an excellent way to track changes to your inventory and host variables. +.. _how_we_merge: + +How Variables Are Merged +++++++++++++++++++++++++ + +By default variables are merged/flattened to the specific host before a play is run. This keeps Ansible focused on the Host and Task, so groups don't really surive outside of inventory and host matching. By default, Ansible overwrites variables including the ones defined for a group and/or host (see the `hash_merge` setting to change this) . The order/precedence is (from lowest to highest): + +- all group (becauseit is the 'parent' of all other groups) +- parent group +- child group +- host + +When groups of the same parent/child level are merged, it is done alphabetically, and the last group loaded overwrites the previous groups. For example, an a_group will be merged with b_group and b_group vars that match will overwrite the ones in a_group. + +.. versionadded:: 2.4 + +Starting in Ansible version 2.4, users can use the group variable ``ansible_group_priority`` to change the merge order for groups of the same level (after the parent/child order is resolved). The larger the number, the later it will be merged, giving it higher priority. This variable defaults to ``1`` if not set. For example: + +.. code-block:: yaml + + a_group: + testvar: a + ansible_group_priority: 10 + b_group + testvar: b + +In this example, if both groups have the same priority, the result would normally have been ``testvar == b``, but since we are giving the ``a_group`` a higher priority the result will be ``testvar == a``. + .. _behavioral_parameters: List of Behavioral Inventory Parameters +++++++++++++++++++++++++++++++++++++++ -As alluded to above, setting the following variables controls how ansible interacts with remote hosts. +As described above, setting the following variables control how Ansible interacts with remote hosts. Host connection: diff --git a/docs/docsite/rst/playbooks_variables.rst b/docs/docsite/rst/playbooks_variables.rst index 227235fb2e..bee569bdd3 100644 --- a/docs/docsite/rst/playbooks_variables.rst +++ b/docs/docsite/rst/playbooks_variables.rst @@ -867,6 +867,8 @@ Basically, anything that goes into "role defaults" (the defaults folder inside t If multiple groups have the same variable, the last one loaded wins. If you define a variable twice in a play's vars: section, the 2nd one wins. .. note:: the previous describes the default config `hash_behavior=replace`, switch to 'merge' to only partially overwrite. +.. note:: Group loading follows parent/child relationships. Groups of the same 'patent/child' level are then merged following alphabetical order. + This last one can be superceeded by the user via `ansible_group_priority`, which defaults to 0 for all groups. Another important thing to consider (for all versions) is that connection variables override config, command line and play/role/task specific options and directives. For example:: @@ -1000,7 +1002,7 @@ can set variables in there and make use of them in other roles and elsewhere in - { role: something, foo: 12 } - { role: something_else } -.. note:: There are some protections in place to avoid the need to namespace variables. +.. note:: There are some protections in place to avoid the need to namespace variables. In the above, variables defined in common_settings are most definitely available to 'something' and 'something_else' tasks, but if "something's" guaranteed to have foo set at 12, even if somewhere deep in common settings it set foo to 20.