From 6be42a2a0ec6afb1e8a2f5f48bef4e9c1588dd34 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Thu, 6 Sep 2018 05:06:02 +1000 Subject: [PATCH] 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 --- .../rst/user_guide/playbooks_conditionals.rst | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/docsite/rst/user_guide/playbooks_conditionals.rst b/docs/docsite/rst/user_guide/playbooks_conditionals.rst index 379ab05548..fc6efc3d39 100644 --- a/docs/docsite/rst/user_guide/playbooks_conditionals.rst +++ b/docs/docsite/rst/user_guide/playbooks_conditionals.rst @@ -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, 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:: tasks: @@ -173,15 +173,17 @@ Or with a role:: 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. -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 -tasks within the included file(s). A common situation where this distinction is important is as follows:: +When a conditional is used with ``include_*`` tasks instead of imports, it is applied `only` to the include task itself and not +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 - - include_tasks: other_tasks.yml + - import_tasks: other_tasks.yml # note "import" when: x is not defined # other_tasks.yml @@ -190,8 +192,19 @@ tasks within the included file(s). A common situation where this distinction is - debug: var: x -In the above example, if ``import_tasks`` had been used instead both included tasks would have also been skipped. With ``include_tasks`` -instead, the tasks are executed as expected because the conditional is not applied to them. +This expands at include time to the equivalent of:: + + - 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: