1

I have a simple shell task which is feed with_items. I want to have the 'changed' status only when the run actually did something. So for that I have to parse the output and look for a «Done».

The issue is using a register at the same time that the with_items generates a list of results. And I don't find a way to access the stdout of the current loop iteration.

---
- name: Test to set changed status only on when output match with 'Done'
  hosts: my-host-01
  gather_facts: no

  tasks:
    - name: Task doing stuff
      shell: |
        echo {{ item }}
      register: do_stuff
      with_items:
        - "Doing... Done!"
        - "Nothing to do"
      #changed_when: do_stuff.results[{{ item.id }}].stdout.find('Done')

    - name: Print 'do_stuff' var to debug
      debug:
        var: do_stuff
    - name: Try to access to the desired stdout
      debug:
        var: do_stuff.results[0].stdout

The expected result that I want would be:

TASK [Task doing stuff]
*************************************************************************
changed: [cnode02] => (item=Doing... Done!)
Ok: [cnode02] => (item=Nothing to do)
xenlo
  • 761
  • 1
  • 7
  • 21
  • The following [answer](https://stackoverflow.com/questions/37925282/iteration-using-with-items-and-register) didn't help me as it process it in the next task which is too late to update the task status I assume. – xenlo Nov 19 '18 at 12:03
  • Check this: https://stackoverflow.com/a/43487756/2795592 – Konstantin Suvorov Nov 19 '18 at 12:06
  • That's also done in 2 tasks. It will not help me to have the correct status of my initial task. – xenlo Nov 19 '18 at 12:47

2 Answers2

0

I had a similar problem and the following example from the ansible documentation was very helpful to understand it:

During iteration, the result of the current item will be placed in the variable:

- shell: echo "{{ item }}"
  with_items:
    - one
    - two
  register: echo
  changed_when: echo.stdout != "one"

https://docs.ansible.com/ansible/2.4/playbooks_loops.html#using-register-with-a-loop

In your case the condition with stdout.find(...) will not work. I successfully tested it with '"string" in var.stdout':

- name: Task doing stuff
  shell: |
    echo {{ item }}
  register: do_stuff
  with_items:
    - "Doing... Done!"
    - "Nothing to do"
  changed_when: '"Done" in do_stuff.stdout'
h18c
  • 41
  • 4
0

The following example works using the changed_when: condition, for each item separately.

- name: Task doing stuff
  shell: |
    echo {{ item }}
  register: task_result
  with_items:
    - "Doing... Done!"
    - "Nothing to do"
  changed_when: task_result.stdout | regex_search('Done')

In your task, you must use register: to store the result, e.g. register: task_result. During execution, especially for the changed_when: and failed_when: conditions, this is directly available via the variable name, i.e. via task_result.stdout.

Here you can now e.g. search for the desired text via function regex_search( ), or also for a certain line of the output. To search for a whole line, the function offers multiline=True as another parameter. More information about the function regex_search( ) can be found in the Ansible Docs.

As soon as the task with all its items has been executed, the result (as you assumed) is available in the variable task_result (i.e. under the same name) as a list via the key results, i.e. via task_result.results[ITEM_ID].stdout.

phanaz
  • 1,188
  • 8
  • 17