Search code examples
ansiblejinja2

How can a Jinja template handle versions comparison in Ansible?


I have a file that has all the environments release versions, release_versions:

prod: 10.7.2

dev1: 10.8
dev2: 10.7
dev3: 10.6.2
dev4: 10.7.2
dev5: 10.7.1

I need, in Ansible, to have a template Jinja comparing those versions to the production release version, and tells me which environments need to be updated and which does not, like this:

dev1: 10.8
dev2: 10.7(need to update to 10.7.2)
dev3: 10.6.2(need to update to 10.7.2)
dev4: 10.7.2
dev5: 10.7.1(need to update to 10.7.2)

Since the version can have 3 numbers separate by a dot (.), I cannot use a float format.

Here is my code:

prod_db_version: "10.7.2"

- copy:
    dest: /tmp/version.txt
    content: |
    {% for i in release_versions %}
    {{ i.name }}: {{ i.version }}{% if format(j.version|float) < format(prod_db_version|float) %}(need to update to {{prod_db_version}}){% endif %}
    {% endfor %}

This works if all the versions have only two numbers (e.g.: 10.7).

How can I make this work with versions like 10.7.2?


Solution

  • There is a version test added to Jinja by Ansible for this kind of use case:

    Given the task:

    - debug:
        msg: |
          {%
            for version in release_versions | dict2items
            if version.key != 'prod'
          %}
            {{ version.key }}: {{ version.value }} {%
              if version.value is version(release_versions.prod, '<')
            %}(need to update to {{ release_versions.prod }}){% endif %}
    
          {% endfor %}
      vars:
        release_versions:
          prod: 10.7.2
          dev1: 10.8
          dev2: 10.7
          dev3: 10.6.2
          dev4: 10.7.2
          dev5: 10.7.1
    

    This yields:

    ok: [localhost] => 
      msg: |2-
          dev1: 10.8
          dev2: 10.7 (need to update to 10.7.2)
          dev3: 10.6.2 (need to update to 10.7.2)
          dev4: 10.7.2
          dev5: 10.7.1 (need to update to 10.7.2)