Reputation: 1457
I have a list I'm looping over, the issue is it gives a weird order.
param.yml file:
my_list:
a: val1
b: val2
c: val3
d: val3
Here my simple debug loop:
- name: debug
debug:
msg: "{{ item }}"
loop: "{{ my_list | list }}"
Here the output:
ok: [host] => (item=a) => {
"msg": "a"
}
ok: [host] => (item=c) => {
"msg": "c"
}
ok: [host] => (item=b) => {
"msg": "b"
}
ok: [host] => (item=d) => {
"msg": "d"
}
I'm using ansible 2.10 with python 2.7.5:
ansible --version
ansible 2.10.2
config file = /home/ansible.cfg
configured module search path = [u'/home/ansible/library']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible
python version = 2.7.5 (default, Apr 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
The problem when I switch to python3, it is working as expected:
ok: [host] => (item=a) => {
"msg": "a"
}
ok: [host] => (item=b) => {
"msg": "b"
}
ok: [host] => (item=c) => {
"msg": "c"
}
ok: [host] => (item=d) => {
"msg": "d"
}
Unfortunately, I cannot upgrade the environment to python3 and I need the list to be in the same order as in the param.yml file.
Thank you!
Upvotes: 3
Views: 314
Reputation: 68064
Variable my_list is not a list. It's a dictionary. There is no guarantee in which order a dictionary's keys will be iterated. Use sort filter. For example,
my_keys: "{{ my_list|list|sort }}"
gives
my_keys: [a, b, c, d]
Q: "I need to iterate over it in the same order as it is in the param.yml"
A: It's the wrong data structure for a use case. YAML mapping is an unordered set. You can't "iterate over it in the same order" because there is no order. Use a list of keys. For example,
- debug:
msg: "{{ item }}: {{ my_list[item] }}"
loop: "{{ my_keys }}"
gives (abridged)
msg: 'a: val1'
msg: 'b: val2'
msg: 'c: val3'
msg: 'd: val4'
- debug:
msg: '{ "{{ item }}": "{{ my_list[item] }}" }'
loop: "{{ my_keys }}"
gives (abridged)
msg:
a: val1
msg:
b: val2
msg:
c: val3
msg:
d: val4
- debug:
msg: "{{ item }}"
loop: "{{ my_list|dict2items|sort(attribute='key') }}"
gives (abridged)
msg:
key: a
value: val1
msg:
key: b
value: val2
msg:
key: c
value: val3
msg:
key: d
value: val4
- debug:
msg: "{{ item }}"
loop: "{{ my_list }}"
vars:
my_list:
- a: val1
- b: val2
- c: val3
- d: val4
Example of a complete playbook for testing
- hosts: all
vars:
my_list:
a: val1
b: val2
c: val3
d: val4
my_keys: "{{ my_list|list|sort }}"
my_key2: "{{ my_list.keys()|sort }}"
tasks:
- debug:
var: my_keys|to_yaml
- debug:
var: my_key2|to_yaml
- debug:
msg: "{{ item }}: {{ my_list[item] }}"
loop: "{{ my_keys }}"
tags: t1
- debug:
msg: '{ "{{ item }}": "{{ my_list[item] }}" }'
loop: "{{ my_keys }}"
tags: t2
- debug:
msg: "{{ item }}"
loop: "{{ my_list|dict2items|sort(attribute='key') }}"
tags: t3
- debug:
msg: "{{ item }}"
loop: "{{ my_list }}"
vars:
my_list:
- a: val1
- b: val2
- c: val3
- d: val4
tags: t4
Upvotes: 4