2018-03-14 20:44:21 +01:00
.. _playbooks_loops:
2019-02-26 16:40:13 +01:00
*****
2013-09-29 23:02:53 +02:00
Loops
2019-02-26 16:40:13 +01:00
*****
2013-09-25 07:18:43 +02:00
2019-02-26 16:40:13 +01:00
Sometimes you want to repeat a task multiple times. In computer programming, this is called a loop. Common Ansible loops include changing ownership on several files and/or directories with the :ref: `file module <file_module>` , creating multiple users with the :ref: `user module <user_module>` , and
repeating a polling step until a certain result is reached. Ansible offers two keywords for creating loops: `` loop `` and `` with_<lookup> `` .
2013-10-05 19:50:53 +02:00
2019-02-26 16:40:13 +01:00
.. note ::
* We added `` loop `` in Ansible 2.5. It is not yet a full replacement for `` with_<lookup> `` , but we recommend it for most use cases.
* We have not deprecated the use of `` with_<lookup> `` - that syntax will still be valid for the foreseeable future.
* We are looking to improve `` loop `` syntax - watch this page and the `changelog <https://github.com/ansible/ansible/tree/devel/changelogs> `_ for updates.
2013-09-25 06:26:14 +02:00
2019-02-26 16:40:13 +01:00
.. contents ::
:local:
Comparing `` loop `` and `` with_* ``
=================================
* The `` with_<lookup> `` keywords rely on :ref: `lookup_plugins` - even `` items `` is a lookup.
* The `` loop `` keyword is equivalent to `` with_list `` , and is the best choice for simple loops.
* The `` loop `` keyword will not accept a string as input, see :ref: `query_vs_lookup` .
* Generally speaking, any use of `` with_* `` covered in :ref: `migrating_to_loop` can be updated to use `` loop `` .
* Be careful when changing `` with_items `` to `` loop `` , as `` with_items `` performed implicit single-level flattening. You may need to use `` flatten(1) `` with `` loop `` to match the exact outcome. For example, to get the same output as:
.. code-block :: yaml
with_items:
- 1
- [2,3]
- 4
you would need::
2019-06-18 17:56:33 +02:00
loop: "{{ [1, [2,3] ,4] | flatten(1) }}"
2019-02-26 16:40:13 +01:00
* Any `` with_* `` statement that requires using `` lookup `` within a loop should not be converted to use the `` loop `` keyword. For example, instead of doing:
.. code-block :: yaml
loop: "{{ lookup('fileglob', '*.txt', wantlist=True) }}"
it's cleaner to keep::
with_fileglob: '*.txt'
2013-12-26 20:32:01 +01:00
2013-10-05 00:34:39 +02:00
.. _standard_loops:
2013-09-25 06:26:14 +02:00
2019-02-26 16:40:13 +01:00
Standard loops
==============
Iterating over a simple list
----------------------------
2012-05-13 17:00:02 +02:00
2019-02-26 16:40:13 +01:00
Repeated tasks can be written as standard loops over a simple list of strings. You can define the list directly in the task::
2012-05-13 17:00:02 +02:00
2020-09-15 22:00:09 +02:00
- name: Add several users
ansible.builtin.user:
2017-03-06 23:39:07 +01:00
name: "{{ item }}"
state: present
groups: "wheel"
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop:
2012-05-13 17:00:02 +02:00
- testuser1
- testuser2
2019-02-26 16:40:13 +01:00
You can define the list in a variables file, or in the 'vars' section of your play, then refer to the name of the list in the task::
2012-08-01 04:19:04 +02:00
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop: "{{ somelist }}"
2012-08-01 04:19:04 +02:00
2019-02-26 16:40:13 +01:00
Either of these examples would be the equivalent of::
2012-05-13 17:00:02 +02:00
2020-09-15 22:00:09 +02:00
- name: Add user testuser1
ansible.builtin.user:
2017-03-06 23:39:07 +01:00
name: "testuser1"
state: present
groups: "wheel"
2019-02-26 16:40:13 +01:00
2020-09-15 22:00:09 +02:00
- name: Add user testuser2
ansible.builtin.user:
2017-03-06 23:39:07 +01:00
name: "testuser2"
state: present
groups: "wheel"
2012-05-13 17:00:02 +02:00
2019-12-12 20:20:08 +01:00
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::
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
2020-09-15 22:00:09 +02:00
- name: Optimal yum
ansible.builtin.yum:
2019-02-26 16:40:13 +01:00
name: "{{ list_of_packages }}"
2018-02-03 12:32:11 +01:00
state: present
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
2020-09-15 22:00:09 +02:00
- name: Non-optimal yum, slower and may cause issues with interdependencies
ansible.builtin.yum:
2019-02-26 16:40:13 +01:00
name: "{{ item }}"
2018-02-03 12:32:11 +01:00
state: present
2019-02-26 16:40:13 +01:00
loop: "{{ list_of_packages }}"
Check the :ref: `module documentation <modules_by_category>` to see if you can pass a list to any particular module's parameter(s).
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
2019-02-26 16:40:13 +01:00
Iterating over a list of hashes
-------------------------------
If you have a list of hashes, you can reference subkeys in a loop. For example::
2012-10-17 00:58:31 +02:00
2020-09-15 22:00:09 +02:00
- name: Add several users
ansible.builtin.user:
2017-03-06 23:39:07 +01:00
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop:
2013-05-30 00:05:14 +02:00
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
2012-10-17 00:58:31 +02:00
2019-12-12 20:20:08 +01:00
When combining :ref: `conditionals <playbooks_conditionals>` with a loop, the `` when: `` statement is processed separately for each item.
2019-02-26 16:40:13 +01:00
See :ref: `the_when_statement` for examples.
Iterating over a dictionary
---------------------------
2015-03-06 22:35:49 +01:00
2019-12-12 20:20:08 +01:00
To loop over a dict, use the :ref: `dict2items <dict_filter>` :
.. code-block :: yaml
2018-04-07 11:13:19 +02:00
2020-01-07 16:32:46 +01:00
- name: Using dict2items
2020-09-15 22:00:09 +02:00
ansible.builtin.debug:
2020-01-07 16:32:46 +01:00
msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ tag_data | dict2items }}"
2018-04-07 11:13:19 +02:00
vars:
2020-01-07 16:32:46 +01:00
tag_data:
2018-04-07 11:13:19 +02:00
Environment: dev
Application: payment
2020-01-07 16:32:46 +01:00
Here, we are iterating over `tag_data` and printing the key and the value from it.
2018-04-07 11:13:19 +02:00
2019-02-26 16:40:13 +01:00
Registering variables with a loop
=================================
2017-08-18 22:02:35 +02:00
2019-02-26 16:40:13 +01:00
You can register the output of a loop as a variable. For example::
2018-04-25 19:55:34 +02:00
2020-09-15 22:00:09 +02:00
- name: Register loop output as a variable
ansible.builtin.shell: "echo {{ item }}"
2019-02-26 16:40:13 +01:00
loop:
- "one"
- "two"
register: echo
2018-04-25 19:55:34 +02:00
2019-02-26 16:40:13 +01:00
When you use `` register `` with a loop, the data structure placed in the variable will contain a `` results `` attribute that is a list of all responses from the module. This differs from the data structure returned when using `` register `` without a loop::
2013-12-19 19:11:00 +01:00
{
"changed": true,
"msg": "All items completed",
"results": [
{
"changed": true,
"cmd": "echo \"one\" ",
"delta": "0:00:00.003110",
"end": "2013-12-19 12:00:05.187153",
"invocation": {
"module_args": "echo \"one\"",
"module_name": "shell"
},
"item": "one",
"rc": 0,
"start": "2013-12-19 12:00:05.184043",
"stderr": "",
"stdout": "one"
},
{
"changed": true,
"cmd": "echo \"two\" ",
"delta": "0:00:00.002920",
"end": "2013-12-19 12:00:05.245502",
"invocation": {
"module_args": "echo \"two\"",
"module_name": "shell"
},
"item": "two",
"rc": 0,
"start": "2013-12-19 12:00:05.242582",
"stderr": "",
"stdout": "two"
}
]
}
Subsequent loops over the registered variable to inspect the results may look like::
- name: Fail if return code is not 0
2020-09-15 22:00:09 +02:00
ansible.builtin.fail:
2013-12-19 19:11:00 +01:00
msg: "The command ({{ item.cmd }}) did not have a 0 return code"
when: item.rc != 0
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop: "{{ echo.results }}"
2013-12-19 19:11:00 +01:00
2017-02-28 21:34:39 +01:00
During iteration, the result of the current item will be placed in the variable::
2017-02-03 00:02:28 +01:00
2020-09-15 22:00:09 +02:00
- name: Place the result of the current item in the variable
ansible.builtin.shell: echo "{{ item }}"
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop:
2017-02-03 00:02:28 +01:00
- one
- two
register: echo
changed_when: echo.stdout != "one"
2019-02-26 16:40:13 +01:00
.. _complex_loops:
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
Complex loops
=============
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
Iterating over nested lists
---------------------------
2015-12-02 00:21:10 +01:00
2019-02-26 16:40:13 +01:00
You can use Jinja2 expressions to iterate over complex lists. For example, a loop can combine nested lists::
2020-09-15 22:00:09 +02:00
- name: Give users access to multiple databases
community.mysql.mysql_user:
2019-02-26 16:40:13 +01:00
name: "{{ item[0] }}"
priv: "{{ item[1] }}.*:ALL"
append_privs: yes
password: "foo"
loop: "{{ ['alice', 'bob'] |product(['clientdb', 'employeedb', 'providerdb'])|list }}"
.. _do_until_loops:
Retrying a task until a condition is met
----------------------------------------
.. versionadded :: 1.4
You can use the `` until `` keyword to retry a task until a certain condition is met. Here's an example::
2020-09-15 22:00:09 +02:00
- name: Retry a task until a certain condition is met
ansible.builtin.shell: /usr/bin/foo
2019-02-26 16:40:13 +01:00
register: result
until: result.stdout.find("all systems go") != -1
retries: 5
delay: 10
This task runs up to 5 times with a delay of 10 seconds between each attempt. If the result of any attempt has "all systems go" in its stdout, the task succeeds. The default value for "retries" is 3 and "delay" is 5.
To see the results of individual retries, run the play with `` -vv `` .
When you run a task with `` until `` and register the result as a variable, the registered variable will include a key called "attempts", which records the number of the retries for the task.
.. note :: You must set the `` until `` parameter if you want a task to retry. If `` until `` is not defined, the value for the `` retries `` parameter is forced to 1.
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::
2015-12-02 00:21:10 +01:00
2020-09-15 22:00:09 +02:00
- name: Show all the hosts in the inventory
ansible.builtin.debug:
2017-03-06 23:39:07 +01:00
msg: "{{ item }}"
2018-02-02 13:52:28 +01:00
loop: "{{ groups['all'] }}"
2015-12-02 00:21:10 +01:00
2020-09-15 22:00:09 +02:00
- name: Show all the hosts in the current play
ansible.builtin.debug:
2017-03-06 23:39:07 +01:00
msg: "{{ item }}"
2018-02-02 13:52:28 +01:00
loop: "{{ ansible_play_batch }}"
2015-12-02 00:21:10 +01:00
2016-04-28 15:18:32 +02:00
There is also a specific lookup plugin `` inventory_hostnames `` that can be used like this::
2015-12-02 00:21:10 +01:00
2020-09-15 22:00:09 +02:00
- name: Show all the hosts in the inventory
ansible.builtin.debug:
2017-03-06 23:39:07 +01:00
msg: "{{ item }}"
2018-04-25 19:55:34 +02:00
loop: "{{ query('inventory_hostnames', 'all') }}"
2015-12-02 00:21:10 +01:00
2020-09-15 22:00:09 +02:00
- name: Show all the hosts matching the pattern, ie all but the group www
ansible.builtin.debug:
2017-03-06 23:39:07 +01:00
msg: "{{ item }}"
2019-01-03 15:36:33 +01:00
loop: "{{ query('inventory_hostnames', 'all:!www') }}"
2015-12-02 00:21:10 +01:00
2019-12-12 20:20:08 +01:00
More information on the patterns can be found in :ref: `intro_patterns` .
2015-12-02 00:21:10 +01:00
2019-02-26 16:40:13 +01:00
.. _query_vs_lookup:
2015-10-23 16:31:57 +02:00
2020-09-03 21:47:57 +02:00
Ensuring list input for `` loop `` : using `` query `` rather than `` lookup ``
========================================================================
2015-10-23 16:31:57 +02:00
2019-12-12 20:20:08 +01:00
The `` loop `` keyword requires a list as input, but the `` lookup `` keyword returns a string of comma-separated values by default. Ansible 2.5 introduced a new Jinja2 function named :ref: `query <query>` that always returns a list, offering a simpler interface and more predictable output from lookup plugins when using the `` loop `` keyword.
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
You can force `` lookup `` to return a list to `` loop `` by using `` wantlist=True `` , or you can use `` query `` instead.
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
These examples do the same thing::
2015-10-23 09:27:09 +02:00
2019-02-26 16:40:13 +01:00
loop: "{{ query('inventory_hostnames', 'all') }}"
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
loop: "{{ lookup('inventory_hostnames', 'all', wantlist=True) }}"
.. _loop_control:
2015-10-23 16:31:57 +02:00
2019-02-26 16:40:13 +01:00
Adding controls to loops
========================
.. versionadded :: 2.1
The `` loop_control `` keyword lets you manage your loops in useful ways.
Limiting loop output with `` label ``
-----------------------------------
2016-09-30 16:01:56 +02:00
.. versionadded :: 2.2
2019-02-26 16:40:13 +01:00
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 `` ::
2016-08-31 22:09:37 +02:00
2020-09-15 22:00:09 +02:00
- name: Create servers
2017-03-06 23:39:07 +01:00
digital_ocean:
name: "{{ item.name }}"
state: present
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop:
2016-08-31 22:09:37 +02:00
- name: server1
disks: 3gb
ram: 15Gb
2016-10-21 15:58:09 +02:00
network:
2016-08-31 22:09:37 +02:00
nic01: 100Gb
nic02: 10Gb
...
loop_control:
2017-12-19 12:26:05 +01:00
label: "{{ item.name }}"
2016-08-31 22:09:37 +02:00
2019-02-26 16:40:13 +01:00
The output of this task will display just the `` name `` field for each `` item `` instead of the entire contents of the multi-line `` {{ item }} `` variable.
2016-08-31 22:09:37 +02:00
2019-10-03 17:15:00 +02:00
.. note :: This is for making console output more readable, not protecting sensitive data. If there is sensitive data in `` loop `` , set `` no_log: yes `` on the task to prevent disclosure.
2019-02-26 16:40:13 +01:00
Pausing within a loop
---------------------
2016-09-30 16:01:56 +02:00
.. versionadded :: 2.2
2019-02-26 16:40:13 +01:00
To control the time (in seconds) between the execution of each item in a task loop, use the `` pause `` directive with `` loop_control `` ::
2016-08-31 22:09:37 +02:00
# main.yml
2020-09-15 22:00:09 +02:00
- name: Create servers, pause 3s before creating next
community.digitalocean.digital_ocean:
2017-03-06 23:39:07 +01:00
name: "{{ item }}"
state: present
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 05:32:34 +02:00
loop:
2016-08-31 22:09:37 +02:00
- server1
- server2
2016-09-30 16:01:56 +02:00
loop_control:
2016-08-31 22:09:37 +02:00
pause: 3
2019-02-26 16:40:13 +01:00
Tracking progress through a loop with `` index_var ``
---------------------------------------------------
2018-04-05 20:06:14 +02:00
.. versionadded :: 2.5
2018-01-26 22:29:04 +01:00
2019-02-26 16:40:13 +01:00
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::
2020-09-15 22:00:09 +02:00
- name: Count our fruit
ansible.builtin.debug:
2019-02-26 16:40:13 +01:00
msg: "{{ item }} with index {{ my_idx }}"
loop:
- apple
- banana
- pear
loop_control:
index_var: my_idx
2018-01-26 22:29:04 +01:00
2020-07-13 21:15:44 +02:00
.. note :: `index_var` is 0 indexed.
2019-02-26 16:40:13 +01:00
Defining inner and outer variable names with `` loop_var ``
---------------------------------------------------------
.. versionadded :: 2.1
You can nest two looping tasks using `` include_tasks `` . However, by default Ansible sets the loop variable `` item `` for each loop. This means the inner, nested loop will overwrite the value of `` item `` from the outer loop.
You can specify the name of the variable for each loop using `` loop_var `` with `` loop_control `` ::
# main.yml
- include_tasks: inner.yml
2018-01-26 22:29:04 +01:00
loop:
2019-02-26 16:40:13 +01:00
- 1
- 2
- 3
2018-01-26 22:29:04 +01:00
loop_control:
2019-02-26 16:40:13 +01:00
loop_var: outer_item
# inner.yml
2020-09-15 22:00:09 +02:00
- name: Print outer and inner items
ansible.builtin.debug:
2019-02-26 16:40:13 +01:00
msg: "outer item={{ outer_item }} inner item={{ item }}"
loop:
- a
- b
- c
.. note :: If Ansible detects that the current loop is using a variable which has already been defined, it will raise an error to fail the task.
2015-10-23 16:31:57 +02:00
2019-04-23 23:39:14 +02:00
Extended loop variables
-----------------------
2018-12-07 20:49:50 +01:00
.. versionadded :: 2.8
As of Ansible 2.8 you can get extended loop information using the `` extended `` option to loop control. This option will expose the following information.
========================== ===========
Variable Description
-------------------------- -----------
`` ansible_loop.allitems `` The list of all items in the loop
`` ansible_loop.index `` The current iteration of the loop. (1 indexed)
`` ansible_loop.index0 `` The current iteration of the loop. (0 indexed)
`` ansible_loop.revindex `` The number of iterations from the end of the loop (1 indexed)
`` ansible_loop.revindex0 `` The number of iterations from the end of the loop (0 indexed)
`` ansible_loop.first `` `` True `` if first iteration
`` ansible_loop.last `` `` True `` if last iteration
`` ansible_loop.length `` The number of items in the loop
`` ansible_loop.previtem `` The item from the previous iteration of the loop. Undefined during the first iteration.
`` ansible_loop.nextitem `` The item from the following iteration of the loop. Undefined during the last iteration.
========================== ===========
::
loop_control:
extended: yes
2019-04-23 23:39:14 +02:00
Accessing the name of your loop_var
-----------------------------------
2019-03-26 17:07:54 +01:00
.. versionadded :: 2.8
As of Ansible 2.8 you can get the name of the value provided to `` loop_control.loop_var `` using the `` ansible_loop_var `` variable
For role authors, writing roles that allow loops, instead of dictating the required `` loop_var `` value, you can gather the value via::
"{{ lookup('vars', ansible_loop_var) }}"
2019-02-26 16:40:13 +01:00
.. _migrating_to_loop:
2018-06-01 16:37:21 +02:00
Migrating from with_X to loop
2019-02-26 16:40:13 +01:00
=============================
2018-06-01 16:37:21 +02:00
.. include :: shared_snippets/with2loop.txt
2013-10-05 18:31:16 +02:00
.. seealso ::
2019-02-26 16:40:13 +01:00
:ref: `about_playbooks`
2013-10-05 18:31:16 +02:00
An introduction to playbooks
2019-02-26 16:40:13 +01:00
:ref: `playbooks_reuse_roles`
2013-10-05 18:31:16 +02:00
Playbook organization by roles
2019-02-26 16:40:13 +01:00
:ref: `playbooks_best_practices`
2020-07-14 23:00:44 +02:00
Tips and tricks for playbooks
2019-02-26 16:40:13 +01:00
:ref: `playbooks_conditionals`
2013-10-05 18:31:16 +02:00
Conditional statements in playbooks
2019-02-26 16:40:13 +01:00
:ref: `playbooks_variables`
2013-10-05 18:31:16 +02:00
All about variables
2018-07-21 15:48:47 +02:00
`User Mailing List <https://groups.google.com/group/ansible-devel> `_
2013-10-05 18:31:16 +02:00
Have a question? Stop by the google group!
`irc.freenode.net <http://irc.freenode.net> `_
#ansible IRC chat channel