Ansible register result of multiple commands

A slightly different situation, which took a while to figure out. If you want to use the results of multiple items, but for changed_when, then the register variable will not have a var.results! Instead, changed_when, is evaluated for each item, and you can just directly use the register var.

Simple example, which will result in changed: false:

- action: command echo {{item}}
  register: out
  changed_when: "'z' in out.stdout"
  with_items:
    - hello
    - foo
    - bye

Another example:

- name: Create fulltext index for faster text searches.
  mysql_db: name={{SO_database}} state=import target=/tmp/fulltext-{{item.tableName}}-{{item.columnName}}.sql
  with_items: 
    - {tableName: Posts,  columnName: Title}
    - {tableName: Posts,  columnName: Body}
    - {tableName: Posts,  columnName: Tags}
    - {tableName: Comments, columnName: Text}
  register: createfulltextcmd
  changed_when: createindexcmd.msg.find('already exists') == -1

Finally, when you do want to loop through results in other contexts, it does seem a bit tricky to programmatically access the index as that is not exposed. I did find this one example that might be promising:

- name: add hosts to known_hosts
shell: 'ssh-keyscan -H {{item.host}}>> /home/testuser/known_hosts'
with_items:
  - { index: 0, host: testhost1.test.dom }
  - { index: 1, host: testhost2.test.dom }
  - { index: 2, host: 192.168.202.100 }
when: ssh_known_hosts.results[{{item.index}}].rc == 1

Posting because I can't comment yet

Relating to gameweld's answer, since Ansible 2.5 there's another way to accessing the iteration index.

From the docs:

Tracking progress through a loop with index_var

New in version 2.5.

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:
    msg: "{{ item }} with index {{ my_idx }}"
  loop:
    - apple
    - banana
    - pear
  loop_control:
    index_var: my_idx

This also allows you to gather results from an array and act later to the same array, taking into account the previous results

- name: Ensure directories exist
  file:
    path: "{{ item }}"
    state: directory
  loop:
    - "mouse"
    - "lizard"
  register: reg

- name: Do something only if directory is new
  debug:
    msg: "New dir created with name '{{ item }}'"
  loop:
   - "mouse"
   - "lizard"
  loop_control:
    index_var: index
  when: reg.results[index].changed

Please note that the "mouse lizard" array should be exactly the same


Starting in Ansible 1.6.1, the results registered with multiple items are stored in result.results as an array. So you can use result.results[0].stdout and so on.

Testing playbook:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - command: "echo {{item}}"
      register: result
      with_items: [1, 2]
    - debug:
        var: result

Result:

$ ansible-playbook -i localhost, test.yml

PLAY [localhost] ************************************************************** 

TASK: [command echo {{item}}] ************************************************* 
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)

TASK: [debug ] **************************************************************** 
ok: [localhost] => {
    "var": {
        "result": {
            "changed": true, 
            "msg": "All items completed", 
            "results": [
                {
                    "changed": true, 
                    "cmd": [
                        "echo", 
                        "1"
                    ], 
                    "delta": "0:00:00.002502", 
                    "end": "2015-08-07 16:44:08.901313", 
                    "invocation": {
                        "module_args": "echo 1", 
                        "module_name": "command"
                    }, 
                    "item": 1, 
                    "rc": 0, 
                    "start": "2015-08-07 16:44:08.898811", 
                    "stderr": "", 
                    "stdout": "1", 
                    "stdout_lines": [
                        "1"
                    ], 
                    "warnings": []
                }, 
                {
                    "changed": true, 
                    "cmd": [
                        "echo", 
                        "2"
                    ], 
                    "delta": "0:00:00.002516", 
                    "end": "2015-08-07 16:44:09.038458", 
                    "invocation": {
                        "module_args": "echo 2", 
                        "module_name": "command"
                    }, 
                    "item": 2, 
                    "rc": 0, 
                    "start": "2015-08-07 16:44:09.035942", 
                    "stderr": "", 
                    "stdout": "2", 
                    "stdout_lines": [
                        "2"
                    ], 
                    "warnings": []
                }
            ]
        }
    }
}

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

Tags:

Ansible