# How to sort a loop based upon a key value - weird behaviour using win\_dsc

**URL:** <https://forum.ansible.com/t/how-to-sort-a-loop-based-upon-a-key-value-weird-behaviour-using-win-dsc/29486>\
**Category:** Ansible Project\
**Created:** [January 21, 2019, 8:49pm UTC](https://forum.ansible.com/t/how-to-sort-a-loop-based-upon-a-key-value-weird-behaviour-using-win-dsc/29486 "2019-01-21T20:49:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lee\_Drew](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lee\_Drew](https://forum.ansible.com/u/Lee_Drew)\
**Post date:** [January 21, 2019, 8:49pm UTC](https://forum.ansible.com/t/how-to-sort-a-loop-based-upon-a-key-value-weird-behaviour-using-win-dsc/29486/1 "2019-01-21T20:49:23Z")

</div>

Hi - I’ve got a few questions…I have a variable (dictionary with lists I think is what it is? Is this the correct name/term?)

`  
dns\_nat\_dc1\_records:

- { zone: ‘[test.com](http://test.com)’, name: ‘server1’, target: ‘192.168.1.10’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server2’, target: ‘192.168.1.11’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘crl’, target: ‘192.168.1.12’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server1’, target: ‘192.168.100.10’, type: ‘ARecord’, state: ‘absent’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server2’, target: ‘192.168.100.11’, type: ‘ARecord’, state: ‘absent’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘crl’, target: ‘192.168.100.12’, type: ‘ARecord’, state: ‘absent’ }  
`

`  
dns\_nat\_dc2\_records:

- { zone: ‘[test.com](http://test.com)’, name: ‘server1’, target: ‘192.168.100.10’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server2’, target: ‘192.168.100.11’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘crl’, target: ‘192.168.100.12’, type: ‘ARecord’, state: ‘present’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server1’, target: ‘192.168.1.10’, type: ‘ARecord’, state: ‘absent’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘server2’, target: ‘192.168.1.11’, type: ‘ARecord’, state: ‘absent’ }
- { zone: ‘[test.com](http://test.com)’, name: ‘crl’, target: ‘192.168.1.12’, type: ‘ARecord’, state: ‘absent’ }  
`

I have a couple of plays…

- name: Ensure DNS NAT A/CNAME Records are present/absent for running in DC1  
win\_dsc:  
resource\_name: xDnsRecord  
Zone: “{{ item.zone }}”  
Name: “{{ item.name }}”  
Target: “{{ item.target }}”  
Type: “{{ item.type }}”  
Ensure: “{{ item.state }}”  
loop: “{{ dns\_nat\_dc1\_records }}”

when: (env == ‘dev’ or env == ‘stg’) and active\_site == ‘dc1’

- name: Ensure DNS NAT A/CNAME Records are present/absent for running in DC2  
win\_dsc:  
resource\_name: xDnsRecord  
Zone: “{{ item.zone }}”  
Name: “{{ item.name }}”  
Target: “{{ item.target }}”  
Type: “{{ item.type }}”  
Ensure: “{{ item.state }}”  
loop: “{{ dns\_nat\_dc2\_records }}”

when: (env == ‘dev’ or env == ‘stg’) and active\_site == ‘dc2’

What I’ve observed (whether I’m running either task in the play) is the DNS entries aren’t present if I specify the state of “absent”. If these lines are commented out the entries are created (and if running the play multiple times and specifying the remote site (e.g dc2 instead of dc1 to trigger the dc2 play task) duplicate DNS entries will be created of the hostname (different IP as expected).

I’ve debugged the play and it appears to be looping through in correct order - I’ve read older posts on forums where apparently dictionary’s are looped in random order (is this still true - I haven’t seen it). For clarification - the vars I listed above - that is a dictionary with a list right?

Can I loop through the var by first running through the key of “state” and value of “absent”. I was trying to use dictsort on the loop but couldn’t get the correct syntax. E.g loop: “{{ dns\_nat\_dc1\_records | dictsort(false,‘absent’) }}”

Have I missed anything obvious?

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [January 21, 2019, 8:57pm UTC](https://forum.ansible.com/t/how-to-sort-a-loop-based-upon-a-key-value-weird-behaviour-using-win-dsc/29486/2 "2019-01-21T20:57:18Z")

</div>

You have the terms backwards. You have a list of dicts, not a dict of lists. As such, you will want to use `sort` instead of `dictsort`

In python dicts are not guaranteed to maintain insertion order, depending on the python version. However, lists are guaranteed to maintain insertion order.

So you have a few options, either manually sort them the way you want. Or use the `sort` filter. One thing to note is that the `sort` filter, while you can sort by attribute, it doesn’t allow you to specify what value you want first. It just does alphanumeric sorting, which should be ok with `present`/`absent`. If you need more control, you would need to use something like `selectattr` and concatenate results.

---

<div class="post-metadata">

**Author:** ![Lee\_Drew](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lee\_Drew](https://forum.ansible.com/u/Lee_Drew)\
**Post date:** [January 22, 2019, 2:20am UTC](https://forum.ansible.com/t/how-to-sort-a-loop-based-upon-a-key-value-weird-behaviour-using-win-dsc/29486/3 "2019-01-22T02:20:40Z")

</div>

Thanks Matt. Using the sort filter worked a treat on the attribute “state” - sorted my issue.
