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::
- name: add several users
user:
- name: Add several users
ansible.builtin.user:
name: "{{ item }}"
state: present
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::
- name: add user testuser1
user:
- name: Add user testuser1
ansible.builtin.user:
name: "testuser1"
state: present
groups: "wheel"
- name: add user testuser2
user:
- name: Add user testuser2
ansible.builtin.user:
name: "testuser2"
state: present
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::
- name: optimal yum
yum:
- name: Optimal yum
ansible.builtin.yum:
name: "{{ list_of_packages }}"
state: present
- name: non-optimal yum, slower and may cause issues with interdependencies
yum:
- name: Non-optimal yum, slower and may cause issues with interdependencies
ansible.builtin.yum:
name: "{{ item }}"
state: present
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::
- name: add several users
user:
- name: Add several users
ansible.builtin.user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
@ -122,7 +122,7 @@ To loop over a dict, use the :ref:`dict2items <dict_filter>`:
.. code-block:: yaml
- name: Using dict2items
debug:
ansible.builtin.debug:
msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ tag_data | dict2items }}"
vars:
@ -137,7 +137,8 @@ Registering variables with a loop
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:
- "one"
- "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::
- name: Fail if return code is not 0
fail:
ansible.builtin.fail:
msg: "The command ({{ item.cmd }}) did not have a 0 return code"
when: item.rc != 0
loop: "{{ echo.results }}"
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:
- one
- 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::
- name: give users access to multiple databases
mysql_user:
- name: Give users access to multiple databases
community.mysql.mysql_user:
name: "{{ item[0] }}"
priv: "{{ item[1] }}.*:ALL"
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::
- shell: /usr/bin/foo
- name: Retry a task until a certain condition is met
ansible.builtin.shell: /usr/bin/foo
register: result
until: result.stdout.find("all systems go") != -1
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::
# show all the hosts in the inventory
- debug:
- name: Show all the hosts in the inventory
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ groups['all'] }}"
# show all the hosts in the current play
- debug:
- name: Show all the hosts in the current play
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ ansible_play_batch }}"
There is also a specific lookup plugin ``inventory_hostnames`` that can be used like this::
# show all the hosts in the inventory
- debug:
- name: Show all the hosts in the inventory
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'all') }}"
# show all the hosts matching the pattern, ie all but the group www
- debug:
- name: Show all the hosts matching the pattern, ie all but the group www
ansible.builtin.debug:
msg: "{{ item }}"
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``::
- name: create servers
- name: Create servers
digital_ocean:
name: "{{ item.name }}"
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``::
# main.yml
- name: create servers, pause 3s before creating next
digital_ocean:
- name: Create servers, pause 3s before creating next
community.digitalocean.digital_ocean:
name: "{{ item }}"
state: present
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::
- name: count our fruit
debug:
- name: Count our fruit
ansible.builtin.debug:
msg: "{{ item }} with index {{ my_idx }}"
loop:
- apple
@ -371,7 +374,8 @@ You can specify the name of the variable for each loop using ``loop_var`` with `
loop_var: outer_item
# inner.yml
- debug:
- name: Print outer and inner items
ansible.builtin.debug:
msg: "outer item={{ outer_item }} inner item={{ item }}"
loop:
- a

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

Loading…
Cancel
Save