Srinivasan Gunasekaran
Srinivasan Gunasekaran

Reputation: 191

Ansible Version Forcing

We have multiple versions of ansible(2.3,2.3.0,2.8.6) we want to use a particular version '2.8.6'.

But whenever ansible execution starts, it uses a different version 2.4.2.0. If we check ansible --version it is ansible-playbook 2.4.2.0.

Is ansible and ansible-playbook versions are same? How to force a version in ansible execution?

Please give your inputs.

Upvotes: 4

Views: 1194

Answers (1)

George Shuklin
George Shuklin

Reputation: 7877

Ansible is well-known to subtly break compatibility around variables, roles, includes and delegation. Therefore, it's considered to be the best practice to assert an Ansible version in a playbook before doing anything.

There are few things to assure:

  1. Those checks should survive --tags option.
  2. Those checks should survive --limit
  3. Those checks should be relatively fast and cause as less verbosity as possible.

My current solution is:

  1. Create playbook version_check.yaml
  2. - import_playbook: version_check.yaml at the beginning of each playbook. (each, this is important, trust me).

version_check.yaml content (ansible 2.5+):

- hosts: all, localhost
  gather_facts: false
  run_once: true
  tasks:
  - name: Check ansible version
    assert:
      that:
        - "ansible_version.full is version('2.8.0', '>=')"
        - "ansible_version.full is version('2.9.0', '<')"
      msg: >
          Use Ansible to 2.8 to run this playbook
    delegate_to: localhost
    tags:
    - always

As you can see, there are a lot here.

  1. run_once do this once per Ansible run.
  2. gather_facts: false speed it up a bit.
  3. It is assigned to 'all, localhost', basically guaranee that it's in Ansible runlist regardless of any --limit
  4. It has tag always almost guarantee to run in the case of use --tags. The single uncovered hole here is to use --skip always (which is insane).

There is an older answer with older syntax for versions (below 2.5):

- hosts: all, localhost
  gather_facts: false
  run_once: true
  tasks:
  - name: Check ansible version
    assert:
      that:
        - "ansible_version.full | version_compare('2.8.0', '>=')"
        - "ansible_version.full | version_compare('2.9.0', '<')"
      msg: >
          Use Ansible to 2.8 to run this playbook
    delegate_to: localhost
    tags:
    - always

It's hard to say which version to use. If you are afraid of very old ansible, version_compare is better than version, but if you are sure it's at least 2.5+, you can use newer version syntax.

Upvotes: 3

Related Questions