Docsite: improve playbooks_loops.rst (#71718)

pull/71770/head
Andrew Klychkov 4 years ago committed by GitHub
parent fdf80690e4
commit 13ab9f5932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -55,8 +55,8 @@ Iterating over a simple list
Repeated tasks can be written as standard loops over a simple list of strings. You can define the list directly in the task:: Repeated tasks can be written as standard loops over a simple list of strings. You can define the list directly in the task::
- name: add several users - name: Add several users
user: ansible.builtin.user:
name: "{{ item }}" name: "{{ item }}"
state: present state: present
groups: "wheel" groups: "wheel"
@ -70,27 +70,27 @@ You can define the list in a variables file, or in the 'vars' section of your pl
Either of these examples would be the equivalent of:: Either of these examples would be the equivalent of::
- name: add user testuser1 - name: Add user testuser1
user: ansible.builtin.user:
name: "testuser1" name: "testuser1"
state: present state: present
groups: "wheel" groups: "wheel"
- name: add user testuser2 - name: Add user testuser2
user: ansible.builtin.user:
name: "testuser2" name: "testuser2"
state: present state: present
groups: "wheel" groups: "wheel"
You can pass a list directly to a parameter for some plugins. Most of the packaging modules, like :ref:`yum <yum_module>` and :ref:`apt <apt_module>`, have this capability. When available, passing the list to a parameter is better than looping over the task. For example:: You can pass a list directly to a parameter for some plugins. Most of the packaging modules, like :ref:`yum <yum_module>` and :ref:`apt <apt_module>`, have this capability. When available, passing the list to a parameter is better than looping over the task. For example::
- name: optimal yum - name: Optimal yum
yum: ansible.builtin.yum:
name: "{{ list_of_packages }}" name: "{{ list_of_packages }}"
state: present state: present
- name: non-optimal yum, slower and may cause issues with interdependencies - name: Non-optimal yum, slower and may cause issues with interdependencies
yum: ansible.builtin.yum:
name: "{{ item }}" name: "{{ item }}"
state: present state: present
loop: "{{ list_of_packages }}" loop: "{{ list_of_packages }}"
@ -102,8 +102,8 @@ Iterating over a list of hashes
If you have a list of hashes, you can reference subkeys in a loop. For example:: If you have a list of hashes, you can reference subkeys in a loop. For example::
- name: add several users - name: Add several users
user: ansible.builtin.user:
name: "{{ item.name }}" name: "{{ item.name }}"
state: present state: present
groups: "{{ item.groups }}" groups: "{{ item.groups }}"
@ -122,7 +122,7 @@ To loop over a dict, use the :ref:`dict2items <dict_filter>`:
.. code-block:: yaml .. code-block:: yaml
- name: Using dict2items - name: Using dict2items
debug: ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}" msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ tag_data | dict2items }}" loop: "{{ tag_data | dict2items }}"
vars: vars:
@ -137,7 +137,8 @@ Registering variables with a loop
You can register the output of a loop as a variable. For example:: You can register the output of a loop as a variable. For example::
- shell: "echo {{ item }}" - name: Register loop output as a variable
ansible.builtin.shell: "echo {{ item }}"
loop: loop:
- "one" - "one"
- "two" - "two"
@ -185,14 +186,15 @@ When you use ``register`` with a loop, the data structure placed in the variable
Subsequent loops over the registered variable to inspect the results may look like:: Subsequent loops over the registered variable to inspect the results may look like::
- name: Fail if return code is not 0 - name: Fail if return code is not 0
fail: ansible.builtin.fail:
msg: "The command ({{ item.cmd }}) did not have a 0 return code" msg: "The command ({{ item.cmd }}) did not have a 0 return code"
when: item.rc != 0 when: item.rc != 0
loop: "{{ echo.results }}" loop: "{{ echo.results }}"
During iteration, the result of the current item will be placed in the variable:: During iteration, the result of the current item will be placed in the variable::
- shell: echo "{{ item }}" - name: Place the result of the current item in the variable
ansible.builtin.shell: echo "{{ item }}"
loop: loop:
- one - one
- two - two
@ -209,8 +211,8 @@ Iterating over nested lists
You can use Jinja2 expressions to iterate over complex lists. For example, a loop can combine nested lists:: You can use Jinja2 expressions to iterate over complex lists. For example, a loop can combine nested lists::
- name: give users access to multiple databases - name: Give users access to multiple databases
mysql_user: community.mysql.mysql_user:
name: "{{ item[0] }}" name: "{{ item[0] }}"
priv: "{{ item[1] }}.*:ALL" priv: "{{ item[1] }}.*:ALL"
append_privs: yes append_privs: yes
@ -227,7 +229,8 @@ Retrying a task until a condition is met
You can use the ``until`` keyword to retry a task until a certain condition is met. Here's an example:: You can use the ``until`` keyword to retry a task until a certain condition is met. Here's an example::
- shell: /usr/bin/foo - name: Retry a task until a certain condition is met
ansible.builtin.shell: /usr/bin/foo
register: result register: result
until: result.stdout.find("all systems go") != -1 until: result.stdout.find("all systems go") != -1
retries: 5 retries: 5
@ -246,25 +249,25 @@ Looping over inventory
To loop over your inventory, or just a subset of it, you can use a regular ``loop`` with the ``ansible_play_batch`` or ``groups`` variables:: To loop over your inventory, or just a subset of it, you can use a regular ``loop`` with the ``ansible_play_batch`` or ``groups`` variables::
# show all the hosts in the inventory - name: Show all the hosts in the inventory
- debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ groups['all'] }}" loop: "{{ groups['all'] }}"
# show all the hosts in the current play - name: Show all the hosts in the current play
- debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ ansible_play_batch }}" loop: "{{ ansible_play_batch }}"
There is also a specific lookup plugin ``inventory_hostnames`` that can be used like this:: There is also a specific lookup plugin ``inventory_hostnames`` that can be used like this::
# show all the hosts in the inventory - name: Show all the hosts in the inventory
- debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'all') }}" loop: "{{ query('inventory_hostnames', 'all') }}"
# show all the hosts matching the pattern, ie all but the group www - name: Show all the hosts matching the pattern, ie all but the group www
- debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'all:!www') }}" loop: "{{ query('inventory_hostnames', 'all:!www') }}"
@ -300,7 +303,7 @@ Limiting loop output with ``label``
When looping over complex data structures, the console output of your task can be enormous. To limit the displayed output, use the ``label`` directive with ``loop_control``:: When looping over complex data structures, the console output of your task can be enormous. To limit the displayed output, use the ``label`` directive with ``loop_control``::
- name: create servers - name: Create servers
digital_ocean: digital_ocean:
name: "{{ item.name }}" name: "{{ item.name }}"
state: present state: present
@ -326,8 +329,8 @@ Pausing within a loop
To control the time (in seconds) between the execution of each item in a task loop, use the ``pause`` directive with ``loop_control``:: To control the time (in seconds) between the execution of each item in a task loop, use the ``pause`` directive with ``loop_control``::
# main.yml # main.yml
- name: create servers, pause 3s before creating next - name: Create servers, pause 3s before creating next
digital_ocean: community.digitalocean.digital_ocean:
name: "{{ item }}" name: "{{ item }}"
state: present state: present
loop: loop:
@ -342,8 +345,8 @@ Tracking progress through a loop with ``index_var``
To keep track of where you are in a loop, use the ``index_var`` directive with ``loop_control``. This directive specifies a variable name to contain the current loop index:: To keep track of where you are in a loop, use the ``index_var`` directive with ``loop_control``. This directive specifies a variable name to contain the current loop index::
- name: count our fruit - name: Count our fruit
debug: ansible.builtin.debug:
msg: "{{ item }} with index {{ my_idx }}" msg: "{{ item }} with index {{ my_idx }}"
loop: loop:
- apple - apple
@ -371,7 +374,8 @@ You can specify the name of the variable for each loop using ``loop_var`` with `
loop_var: outer_item loop_var: outer_item
# inner.yml # inner.yml
- debug: - name: Print outer and inner items
ansible.builtin.debug:
msg: "outer item={{ outer_item }} inner item={{ item }}" msg: "outer item={{ outer_item }} inner item={{ item }}"
loop: loop:
- a - a

@ -10,14 +10,14 @@ with_list
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_list - name: with_list
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
with_list: with_list:
- one - one
- two - two
- name: with_list -> loop - name: with_list -> loop
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: loop:
- one - one
@ -31,12 +31,12 @@ with_items
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_items - name: with_items
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
with_items: "{{ items }}" with_items: "{{ items }}"
- name: with_items -> loop - name: with_items -> loop
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ items|flatten(levels=1) }}" loop: "{{ items|flatten(levels=1) }}"
@ -48,12 +48,12 @@ with_indexed_items
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_indexed_items - name: with_indexed_items
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
with_indexed_items: "{{ items }}" with_indexed_items: "{{ items }}"
- name: with_indexed_items -> loop - name: with_indexed_items -> loop
debug: ansible.builtin.debug:
msg: "{{ index }} - {{ item }}" msg: "{{ index }} - {{ item }}"
loop: "{{ items|flatten(levels=1) }}" loop: "{{ items|flatten(levels=1) }}"
loop_control: loop_control:
@ -67,12 +67,12 @@ with_flattened
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_flattened - name: with_flattened
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
with_flattened: "{{ items }}" with_flattened: "{{ items }}"
- name: with_flattened -> loop - name: with_flattened -> loop
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
loop: "{{ items|flatten }}" loop: "{{ items|flatten }}"
@ -84,14 +84,14 @@ with_together
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_together - name: with_together
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
with_together: with_together:
- "{{ list_one }}" - "{{ list_one }}"
- "{{ list_two }}" - "{{ list_two }}"
- name: with_together -> loop - name: with_together -> loop
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ list_one|zip(list_two)|list }}" loop: "{{ list_one|zip(list_two)|list }}"
@ -100,7 +100,7 @@ Another example with complex data
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_together -> loop - name: with_together -> loop
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }} - {{ item.2 }}" msg: "{{ item.0 }} - {{ item.1 }} - {{ item.2 }}"
loop: "{{ data[0]|zip(*data[1:])|list }}" loop: "{{ data[0]|zip(*data[1:])|list }}"
vars: vars:
@ -117,17 +117,17 @@ with_dict
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_dict - name: with_dict
debug: ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}" msg: "{{ item.key }} - {{ item.value }}"
with_dict: "{{ dictionary }}" with_dict: "{{ dictionary }}"
- name: with_dict -> loop (option 1) - name: with_dict -> loop (option 1)
debug: ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}" msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ dictionary|dict2items }}" loop: "{{ dictionary|dict2items }}"
- name: with_dict -> loop (option 2) - name: with_dict -> loop (option 2)
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ dictionary|dictsort }}" loop: "{{ dictionary|dictsort }}"
@ -139,12 +139,12 @@ with_sequence
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_sequence - name: with_sequence
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
with_sequence: start=0 end=4 stride=2 format=testuser%02x with_sequence: start=0 end=4 stride=2 format=testuser%02x
- name: with_sequence -> loop - name: with_sequence -> loop
debug: ansible.builtin.debug:
msg: "{{ 'testuser%02x' | format(item) }}" msg: "{{ 'testuser%02x' | format(item) }}"
# range is exclusive of the end point # range is exclusive of the end point
loop: "{{ range(0, 4 + 1, 2)|list }}" loop: "{{ range(0, 4 + 1, 2)|list }}"
@ -157,14 +157,14 @@ with_subelements
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_subelements - name: with_subelements
debug: ansible.builtin.debug:
msg: "{{ item.0.name }} - {{ item.1 }}" msg: "{{ item.0.name }} - {{ item.1 }}"
with_subelements: with_subelements:
- "{{ users }}" - "{{ users }}"
- mysql.hosts - mysql.hosts
- name: with_subelements -> loop - name: with_subelements -> loop
debug: ansible.builtin.debug:
msg: "{{ item.0.name }} - {{ item.1 }}" msg: "{{ item.0.name }} - {{ item.1 }}"
loop: "{{ users|subelements('mysql.hosts') }}" loop: "{{ users|subelements('mysql.hosts') }}"
@ -176,14 +176,14 @@ with_nested/with_cartesian
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_nested - name: with_nested
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
with_nested: with_nested:
- "{{ list_one }}" - "{{ list_one }}"
- "{{ list_two }}" - "{{ list_two }}"
- name: with_nested -> loop - name: with_nested -> loop
debug: ansible.builtin.debug:
msg: "{{ item.0 }} - {{ item.1 }}" msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ list_one|product(list_two)|list }}" loop: "{{ list_one|product(list_two)|list }}"
@ -195,11 +195,11 @@ with_random_choice
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
- name: with_random_choice - name: with_random_choice
debug: ansible.builtin.debug:
msg: "{{ item }}" msg: "{{ item }}"
with_random_choice: "{{ my_list }}" with_random_choice: "{{ my_list }}"
- name: with_random_choice -> loop (No loop is needed here) - name: with_random_choice -> loop (No loop is needed here)
debug: ansible.builtin.debug:
msg: "{{ my_list|random }}" msg: "{{ my_list|random }}"
tags: random tags: random

Loading…
Cancel
Save