Philip Shangguan
Philip Shangguan

Reputation: 527

How to sort a list by its attribute in Ansible?

I have a list of strings and the dates associated to each string. I want to sort the list by the date and pickup the latest string.

Here is the code:

- debug: msg="{{ sort_list }}"

- debug: msg="{{_latest.snap_name }}"
  loop: "{{ sort_list }}"
    vars:
      _latest: "{{ item | sort(attribute='date')|last }}"

and the output is:

ok: [localhost] => {
    "msg": [
        {
            "date": "20220602020004",
            "snap_name": "aaa-bbb-ccc-data-sb-20220602020004"
        },
        {
            "date": "20220603020004",
            "snap_name": "aaa-bbb-ccc-data-sb-20220603020004"
        },
        {
            "date": "20220604020004",
            "snap_name": "aaa-bbb-ccc-data-sb-20220604020004"
        }
    ]
}

TASK [debug] *****************************************************
Sunday 05 June 2022  18:22:30 +0000 (0:00:00.055)       0:00:04.777 *********** 
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: {{ item | sort(attribute='date')|last }}: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'date'\n\nThe error appears to be in '/home/philip.shangguan/code/devops/google/ansible/test-scripts/philip/prodcopy/a.yml': line 128, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n      - debug: msg=\"{{_latest.snap_name }}\"\n        ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n    with_items:\n      - {{ foo }}\n\nShould be written as:\n\n    with_items:\n      - \"{{ foo }}\"\n"}

The first debug gives the list. Then I want to pick up the string zzz-wag-chicken-data-sb-20220604020004 which has the latest date.

What is missing/wrong in my code with the second debug?

Upvotes: 2

Views: 9391

Answers (1)

flowerysong
flowerysong

Reputation: 2919

You're looping over the entire list and then passing individual items to sort, when what you want to do is just pass the list to sort.

      - debug:
          msg: "{{ _latest.snap_name }}"
        vars:
          _latest: "{{ sort_list | sort(attribute='date') | last }}"

You can also do it without the intermediate variable:

      - debug:
          msg: "{{ (sort_list | sort(attribute='date') | last).snap_name }}"

Upvotes: 6

Related Questions