Given the following playbook:
---
- name: Check if log directory exists - Step 1
stat: path="{{ wl_base }}/{{ item.0.name }}/{{ wl_dom }}/servers/{{ item.1 }}/logs" get_md5=no
register: log_dir
with_subelements:
- wl_instances
- servers
- name: Check if log directory exists - Step 2
fail: msg="Log directory does not exists or it is not a symlink."
failed_when: >
log_dir.results[0].stat.islnk is not defined
or log_dir.results[0].stat.islnk != true
or log_dir.results[0].stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
with_subelements:
- wl_instances
- servers
that is using the following vars:
---
wl_instances:
- name: aservers
servers:
- AdminServer
- name: mservers
servers:
- "{{ ansible_hostname }}"
the second task currently only uses one of the two possible results (results[0]
).
My question is: how could I iterate over all available items stored in log_dir.results
?
A sample output debug:hostvars[inventory_hostname]
follows:
"log_dir": {
"changed": false,
"msg": "All items completed",
"results": [
{
"changed": false,
"invocation": {
"module_args": "path=\"/path/to/servers/aservers/domain/AdminServer/logs\" get_md5=no",
"module_name": "stat"
},
"item": [
{
"name": "aservers"
},
"AdminServer"
],
"stat": {
...
"lnk_source": "/path/to/logs/domain/AdminServer",
...
}
},
{
"changed": false,
"invocation": {
"module_args": "path=\"/path/to/servers/mservers/domain/servers/some_hostname/logs\" get_md5=no",
"module_name": "stat"
},
"item": [
{
"name": "mservers"
},
"some_hostname"
],
"stat": {
...
"lnk_source": "/path/to/logs/domain/some_hostname",
...
item is not a command, but a variable automatically created and populated by Ansible in tasks which use loops. In the following example: - debug: msg: "{{ item }}" with_items: - first - second. the task will be run twice: first time with the variable item set to first , the second time with second .
Defining inner and outer variable names with loop_var 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 .
Looping over Filetrees. with_filetree recursively matches all files in a directory tree, enabling you to template a complete tree of files on a target system while retaining permissions and ownership.
Ansible documentation recommend user to use or replace with_items with loop. So, with_items is the older way of writing Ansible playbooks and loop is the newer way of writing the playbook. For most part they are almost identical.
Looping over the results in an array (denoted by the []), would be done as
with_items: somelist
or if it's a dict that contains a list, as in this case
with_items: log_dir.results
note this can also be written
with_items: log_dir['results']
so in your task
- name: Check if log directory exists - Step 2
fail: msg="Log directory does not exists or it is not a symlink."
failed_when: >
item.stat.islnk is not defined
or item.stat.islnk != true
or item..stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
with_items: log_dir.results
More information and examples is available in http://docs.ansible.com/playbooks_loops.html#standard-loops.
The main thing here is that you're wanting to access only part of the registered variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With