docs: Clarify include_task v import_tasks with conditionals (#43856)

Correct and clarify "set_fact" example, expanding on what is happening
in the easy-to-get-wrong import mode. Add some additional links to "group_by" documentation and the main import/include discussion.

Closes: #31596
pull/45252/head
Ian Wienand 6 years ago committed by Alicia Cozine
parent 1f3e7ea061
commit 6be42a2a0e

@ -22,7 +22,7 @@ Sometimes you will want to skip a particular step on a particular host.
This could be something as simple as not installing a certain package if the operating system is a particular version, This could be something as simple as not installing a certain package if the operating system is a particular version,
or it could be something like performing some cleanup steps if a filesystem is getting full. or it could be something like performing some cleanup steps if a filesystem is getting full.
This is easy to do in Ansible with the `when` clause, which contains a raw Jinja2 expression without double curly braces (see :doc:`playbooks_variables`). This is easy to do in Ansible with the `when` clause, which contains a raw Jinja2 expression without double curly braces (see :ref:`group_by_module`).
It's actually pretty simple:: It's actually pretty simple::
tasks: tasks:
@ -173,15 +173,17 @@ Or with a role::
when: ansible_os_family == 'Debian' when: ansible_os_family == 'Debian'
You will note a lot of 'skipped' output by default in Ansible when using this approach on systems that don't match the criteria. You will note a lot of 'skipped' output by default in Ansible when using this approach on systems that don't match the criteria.
Read up on the 'group_by' module in the :doc:`modules` docs for a more streamlined way to accomplish the same thing. In many cases the ``group_by`` module (see :doc:`modules`) can be a more streamlined way to accomplish the same thing; see
:ref:`os_variance`.
When used with `include_*` tasks instead of imports, the conditional is applied _only_ to the include task itself and not any other When a conditional is used with ``include_*`` tasks instead of imports, it is applied `only` to the include task itself and not
tasks within the included file(s). A common situation where this distinction is important is as follows:: to any other tasks within the included file(s). A common situation where this distinction is important is as follows::
# include a file to define a variable when it is not already defined # We wish to include a file to define a variable when it is not
# already defined
# main.yml # main.yml
- include_tasks: other_tasks.yml - import_tasks: other_tasks.yml # note "import"
when: x is not defined when: x is not defined
# other_tasks.yml # other_tasks.yml
@ -190,8 +192,19 @@ tasks within the included file(s). A common situation where this distinction is
- debug: - debug:
var: x var: x
In the above example, if ``import_tasks`` had been used instead both included tasks would have also been skipped. With ``include_tasks`` This expands at include time to the equivalent of::
instead, the tasks are executed as expected because the conditional is not applied to them.
- set_fact:
x: foo
when: x is not defined
- debug:
var: x
when: x is not defined
Thus if ``x`` is initially undefined, the ``debug`` task will be skipped. By using ``include_tasks`` instead of ``import_tasks``,
both tasks from ``other_tasks.yml`` will be executed as expected.
For more information on the differences between ``include`` v ``import`` see :ref:`playbooks_reuse`.
.. _conditional_imports: .. _conditional_imports:

Loading…
Cancel
Save