Operating loop results with dict or array

The scenario is that we have two different loops, and we want to operate their result together with a with_nested. So, here we have two loops:

- name: Get home files with names from 1 to 4 
  shell: "ls /home/ansible/{{ item }}"
  ignore_errors: yes
  register: files_1_4
  with_items:
    - 1
    - 2
    - 3
    - 4 #doesn't exist to do the example more interesting

- name: Get home files with names from 5 to 8
  shell: "ls /home/ansible/{{ item }}"
  ignore_errors: yes
  register: files_5_8
  with_items:
    - 5
    - 6
    - 7
    - 8

If you want to operate this together you will need to create a dict (or array) in order to be able to operate them.

So, what we should do is use set_fact to create this dict:

- name: Creating the dict with files that exists
  set_fact:
    existing_files_1_4: "{{ existing_files_1_4|default([]) + [ {'name': item.item } ] }}"
  when: ( item.rc == 0 ) # Just as example
  with_items:
    - "{{ files_1_4.results }}"

- name: Creating the dict with files that exists
  set_fact: 
    existing_files_5_8: "{{ existing_files_5_8|default([]) + [ {'name': item.item } ] }}"
  when: ( item.rc == 0 ) # Just as example
  with_items:
    - "{{ files_5_8.results }}"

And now we’re able to use with_nested with both items. Take into account that we were saving item.item, but you could save item.stdout_lines for example.

- name: Echo result
  shell: "echo {{ item.0.name }} {{ item.1.name }}"
  with_nested:
    - "{{ existing_files_1_4 }}"
    - "{{ existing_files_5_8 }}"
  ignore_errors: yes

And if you check the result you will see something like:

TASK [Echo result] *************************************************************
changed: [server] => (item=[{'name': 1}, {'name': 5}])
changed: [server] => (item=[{'name': 1}, {'name': 6}])
changed: [server] => (item=[{'name': 1}, {'name': 7}])
changed: [server] => (item=[{'name': 2}, {'name': 5}])
changed: [server] => (item=[{'name': 2}, {'name': 6}])
changed: [server] => (item=[{'name': 2}, {'name': 7}])
changed: [server] => (item=[{'name': 3}, {'name': 5}])
changed: [server] => (item=[{'name': 3}, {'name': 6}])
changed: [server] => (item=[{'name': 3}, {'name': 7}])

If instead of using a dict, you want to use an array, you should set_fact as follows

- set_fact:
    existing_files_1_4: "{{ existing_files_1_4|default({}) | combine ( { item.item: item.stdout } ) }}"
  when: (item.rc == 0)
  with_items:
    - "{{ files_1_4.results }}"
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s