I'm building an Ansible playbook in which I want to retrieve the latest version of a software. For this I used "sort" filter in Ansible. That, however, becomes a bit harder, when using version numbers, that are more complex and are not really numbers, e.g. 0.2.1
, 0.10.1
.
This is what I'm doing right now:
- name: Set version to compare
set_fact:
versions:
- "0.1.0"
- "0.1.5"
- "0.11.11"
- "0.9.11"
- "0.9.3"
- "0.10.2"
- "0.6.1"
- "0.6.0"
- "0.11.0"
- "0.6.5"
- name: Sorted list
debug:
msg: "{{ versions | sort }}"
- name: Show the latest element
debug:
msg: "{{ versions | sort | last }}"
The playbook above works, as long as version numbers stay underneath the number 10 (e.g. 0.9.3, but not 0.10.2).
To show the issue:
TASK [Set version to compare] ***************************************************************************************************************
ok: [localhost]
TASK [Sorted list] **************************************************************************************************************************
ok: [localhost] => {
"msg": [
"0.1.0",
"0.1.5",
"0.10.2",
"0.11.0",
"0.11.11",
"0.6.0",
"0.6.1",
"0.6.5",
"0.9.11",
"0.9.3"
]
}
TASK [Show the latest element] **************************************************************************************************************
ok: [localhost] => {
"msg": "0.9.3"
}
In this example the value the desired value is 0.11.11
Does anyone know a good way to sort complex version numbers in Ansible? Any help would be appreciated. Thanks.
An option would be to write a filter plugin. For example,
shell> cat filter_plugins/sort_versions.py
from distutils.version import LooseVersion
def sort_versions(value):
return sorted(value, key=LooseVersion)
class FilterModule(object):
def filters(self):
return {
'sort_versions': sort_versions,
}
Then the task below
- debug:
msg: "{{ versions|sort_versions }}"
gives
msg:
- 0.1.0
- 0.1.5
- 0.6.0
- 0.6.1
- 0.6.5
- 0.9.3
- 0.9.11
- 0.10.2
- 0.11.0
- 0.11.11
You don't have to write the filter if you can install the collection community.general. Use the filter community.general.version_sort. Then, the task below gives the same result
- debug:
msg: "{{ versions|community.general.version_sort }}"
Example of a complete playbook for testing
- hosts: all
vars:
versions:
- '0.1.0'
- '0.1.5'
- '0.11.11'
- '0.9.11'
- '0.9.3'
- '0.10.2'
- '0.6.1'
- '0.6.0'
- '0.11.0'
- '0.6.5'
tasks:
- debug:
msg: "{{ versions|sort_versions }}"
- debug:
msg: "{{ versions|community.general.version_sort }}"