diff --git a/docsite/rst/playbooks_roles.rst b/docsite/rst/playbooks_roles.rst index efae28f5c62..39fbea3bd46 100644 --- a/docsite/rst/playbooks_roles.rst +++ b/docsite/rst/playbooks_roles.rst @@ -143,6 +143,75 @@ inside another. play are going to get the same tasks. ('*when*' provides some ability for hosts to conditionally skip tasks). + +.. _dynamic_static: + +Dynamic vs. Static Includes +``````````````````````````` + +As of Ansible 2.0, the way include tasks are processed was changed. In 1.9.x and lower, includes acted +as a pre-processor statement and were read in during playbook parsing time. This created problems when +variables from sources such as inventory variables like group and host vars (which are not available during +the parsing time) were used in the included file name. + +Ansible 2.0 instead made includes "dynamic", meaning they are not evaluated until the include task is +reached during the play execution. This changed allowed the reintroduction of loops on include statements, +such as the following:: + + - include: foo.yml param={{item}} + with_items: + - 1 + - 2 + - 3 + +It is also possible to use variables from any source with a dynamic include:: + + - include: "{{inventory_hostname}}.yml" + +.. note:: + When an include statement loads different tasks for different hosts, + the ``linear`` strategy keeps the hosts in lock-step by alternating + which hosts are executing tasks while doing a ``noop`` for all other + hosts. For example, if you had hostA, hostB and hostC with the above + example, hostA would execute all of he tasks in hostA.yml while hostB + and hostC waited. It is generally better to do the above with the + ``free`` strategy, which does not force hosts to execute in lock-step. + +Having includes always be dynamic introduced some other limitations, due to the fact that the included +file is not read in until that task is reached during the execution of the play. When using dynamic includes, +it is important to keep these limitations in mind: + +* You cannot use ``notify`` to trigger a handler name which comes from a dynamic include. +* You cannot use ``--start-at-task`` to begin execution at a task inside a dynamic include. +* Tags which only exist inside a dynamic include will not show up in --list-tags output. +* Tasks which only exist inside a dynamic include will not show up in --list-tasks output. + +.. note:: + In Ansible 1.9.x and prior, an error would be raised if a tag name was + used with ``--tags`` or ``--skip-tags``. This error was disabled in Ansible + 2.0 to prevent incorrect failures with tags which only existed inside of + dynamic includes. + +To work around these limitations, Ansible 2.1 introduced the ``static`` option for includes:: + + - include: foo.yml + static: + +By default in Ansible 2.1 and higher, includes will automatically be treated as static rather than +dynamic when the include meets the following conditions: + +* The include does not use any loops. +* The included file name does not use any variables. +* The ``static`` option is not explicitly disabled (ie. ``static: no``). +* The ansible.cfg options to force static includes (see below) are disabled. + +Two options are available in the ansible.cfg configuration for static includes: + +* ``task_includes_static`` - forces all includes in tasks sections to be static. +* ``handler_includes_static`` - forces all includes in handlers sections to be static. + +These options allow users to force playbooks to behave exactly as they did in 1.9.x and before. + .. _roles: Roles