Ansible list not ordered

Viewed 92

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!

1 Answers

Variable my_list is not a list. It's a dictionary. There is no guarantee in which order the keys of a dictionary will be iterated. Use sort filter. For example

    loop: "{{ my_list | list | sort }}"

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 s 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 }}"
      vars:
        my_keys: [a,b,c,d]

gives (abridged)

  msg: 'a: val1'

  msg: 'b: val2'

  msg: 'c: val3'

  msg: 'd: val3'

Below is an example of a list's iteration. The task

    - debug:
        msg: "{{ item }}"
      loop: "{{ my_list }}"
      vars:
        my_list:
          - a: val1
          - b: val2
          - c: val3
          - d: val3

gives (abridged)

  msg:
    a: val1

  msg:
    b: val2

  msg:
    c: val3

  msg:
    d: val3
Related