1

how can I add a condition to ansible task that is based on a loop, when the task itself also based on a loop?

For example, here's my code:

- hosts: all
 gather_facts: False
 vars:
 current_version: 826
 versions:
 - 805
 - 821
 - 824
 - 826
 tasks:
 - name: First Task
 find:
 paths: /Users/tomer/projects/personal/ansible/test
 patterns: snapshot* 
 register: files
 when:
 - current_version == item
 loop: "{{versions}}"
 - name: Second task
 set_fact:
 test_work: "{{ true if item > 0 else false}}"
 loop:
 - "{{ files | json_query('results[*].matched') }}"

So far, this is working as expected. The first task is looking for any file with the name snapshot if the current_version is matching one of the versions in the list.

The second task iterates over the dictionary result from the first task and based on each item it is setting the fact. (In my case, only one item has this attribute).

I wanted to run the second task, only when the first task did run, however, the changed status is always false, so this condition is not useful. I wanted to add the same condition of current_version == item but I can't use item twice here.

Any idea how to achieve that?

asked Dec 9, 2020 at 18:49

1 Answer 1

1

The find command is not really going to change anything, it just queries the file system without doing any modification, so it will indeed always give you a false.

On the other hand, you can definitely use the skipped field of the item.

This said, I would simplify the loop on your set_fact, because there is no real need to use json_query here.

This task would do the job perfectly fine:

- set_fact:
 test_work: "{{ item.matched > 0 }}"
 loop: "{{ files.results }}"
 when: item is not skipped

Another extra tip is to not do things like

true if condition_that_evaluates_to_true else false

But rather do right away

condition_that_evaluates_to_true

Here would be a made up example playbook

- hosts: all
 gather_facts: no
 
 tasks:
 - find:
 path: /tmp
 pattern: dummy*
 when: item == current_version
 register: files
 loop: "{{ versions }}"
 vars:
 current_version: 826
 versions:
 - 805
 - 821
 - 824
 - 826
 - debug:
 msg: "{{ item.matched > 0 }}"
 loop: "{{ files.results }}"
 when: item is not skipped
 loop_control:
 label: "{{ item.item }}"

This would yield the result

PLAY [all] *******************************************************************************************************
TASK [find] ******************************************************************************************************
skipping: [localhost] => (item=805) 
skipping: [localhost] => (item=821) 
skipping: [localhost] => (item=824) 
ok: [localhost] => (item=826)
TASK [debug] *****************************************************************************************************
skipping: [localhost] => (item=805) 
skipping: [localhost] => (item=821) 
skipping: [localhost] => (item=824) 
ok: [localhost] => (item=826) => {
 "msg": true
}
PLAY RECAP *******************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 
answered Dec 9, 2020 at 19:38
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the anser. Here's what I've done: - set_fact: test_work: "{{ item.matched > 0 }}" loop: - "{{ files.results }}" It resulted in this error: The error was: 'list object' has no attribute 'matched
Mind at how I created my loop: loop: "{{ files.results }}" by doing it the way you are, you are actually creating a list of list, which is causing you this error.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.