exit a with_items loop after first successful action

I am working on a project to help our environment get more standardized with regards to LUKS passwords, and I have this as a use case:

given a list of known used passwords for LUKS, I need to loop through the password list until I find the password that opens the luks device using the --test-passphrase option.

once I find the correct password, I can then use it to rebind luks to a new randomly generated password. But I don’t need the loop to continue trying other passwords that won’t work.

I almost need to be able to specify a when condition to break the loop based on the return code of the cryptsetup comand

something like:

  • name: determine correct luks password
    ansible.builtin.shell:
    cmd: echo {{ item }} |cryptsetup --test-passphrase luksOpen {{ luks_dev }}
    register: pw_result
    when: rc == 0

but that won’t work.

my other option would be o use a bash script for this one step, and then go from there.

Just making sure I’m not missing something.

Searching in this august forum I found a thread but it was back in 2020.

That’s not a very can-do attitude. It will work if you reference the variable you registered (instead of a nonexistent variable named rc) and think through the logic of what conditions should result in a skip.

- hosts: localhost
  tasks:
    - shell: exit {{ item }}
      register: result
      failed_when: false
      when:
        - result.rc | default(0) != 2
        - result is not defined or result is not skipped
      loop:
        - 0
        - 1
        - 2
        - 3
        - 0
TASK [shell] *******************************************************************
changed: [localhost] => (item=0)
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)
skipping: [localhost] => (item=3) 
skipping: [localhost] => (item=0) 
3 Likes

2.18 also introduced loop_control.break_when:

5 Likes

for older versions, you can check previous results of the loop

when: pw_result is not defined or pw_result.get('rc')  == 0

This will run the first time, before pw_result is defined and check if it is 0 or not from the last result from 2nd iteration and above. This will skip the rest of the loop, but still run through the whole loop.

1 Like