I need a method to stop looping in Ansible like break
in for
statement in C++ or Bash. For example, I need to the last value before the loop scan to 0.
The default/main.yml
---
os_vars:
- 8
- 10
- 15
- 6
- 0
- 7
- 25
The tasks/main.yml
- name: Debug variables
ansible.builtin.set_fact:
a: "{{ item }}"
loop: "{{ os_vars }}"
when: item > 0
And the output
TASK [test_role : Debug variables] *********************************************
ok: [localhost] => (item=8)
ok: [localhost] => (item=10)
ok: [localhost] => (item=15)
ok: [localhost] => (item=6)
skipping: [localhost] => (item=0)
ok: [localhost] => (item=7)
ok: [localhost] => (item=25)
I know I can set other bool variable to control the looping didn't assign a with following items, but I also need to save time to increase performance of this playbook, as sometime this looping body might be a huge array and we don't need to check the following items when some condition matched ...
Please share your comments. Thanks in advance.
Q: "I know I can set other bool variable to control the looping didn't assign a with following items"
Right, as there are
Similar Q&A
and many more ...
Q: "I need a method to stop looping in Ansible like break
in for
statement in C++ or Bash."
Such is not available. You can't break out the loop, you can only implement to skip.
This is because
Things to know about programming using Ansible
Ansible is not a language: If Ansible isn't a programming language, then what is it? Ansible is a tool written in Python, and it uses the declarative markup language YAML to describe the Desired State of devices and configuration. ... You declare aspects you want to be configured on a target device, such as that a file or directory exists, a package is installed, a service is running, and so on.
Think declaratively: Ansible is a Desired State Engine by design. If you’re trying to “write code” in your plays and roles, you’re setting yourself up for failure. Our YAML-based playbooks were never meant to be for programming.
Q: "I also need to save time to increase performance of this playbook, as sometime this looping body might be a huge array and we don't need to check the following items when some condition matched."
If you like or need to implement such behavior you may need to write something by yourself. See in example Should you develop a module? and Developing modules.
An other approach can be to do some pre-processing on the data structure, os_vars
list to have after that only
os_vars:
- 8
- 10
- 15
- 6
to provide for the loop. Then, no break or if then else construct would be necessary at all.
Further Reading
loop
when the conditional is true
the first time and the threads like Looping a task until it succeeds, How to dynamically end a loop in Ansible, ...break_when
to the loop_control
"loop_control
until
feature"Based on the given comments and as I understood the Use Case a possible solution approach without BREAK
, when:
or any IF
, THEN
, ELSE
construct.
A minimal example playbook
---
- hosts: localhost
become: false
gather_facts: false
vars:
os_vars:
- 8
- 10
- 15
- 6
- 0
- 7
- 25
tasks:
- name: Loop up to idx
debug:
msg: "{{ item }}"
loop: "{{ os_vars[:idx | int] }}"
loop_control:
extended: true
label: "{{ ansible_loop.index }}"
# Get index of zero (0) value
vars:
idx: "{{ os_vars.index(os_vars | min) }}"
will result into an output of
TASK [Loop up to idx] ********
ok: [localhost] => (item=1) =>
msg: 8
ok: [localhost] => (item=2) =>
msg: 10
ok: [localhost] => (item=3) =>
msg: 15
ok: [localhost] => (item=4) =>
msg: 6
Based On