How to check version of ansible before execution begins

I have encounter the issue as follows:

I have used latest ansible version as follows:

{code}
[root@localhost samples]# ansible --version
ansible 2.3.1.0
config file = /home/vagrant/samples/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
{code}

I have designed a module using ‘tempfile’ resouce and working as expected. As per the documentation, I have observed that this is supported from 2.3.x version. However, some of my machines are using 2.2.x version where it throws the exception as follows:

{code}
/include/createTempFile.yml’: line 11, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be:

  • name: Create temp file
    ^ here
    {code}

To avoid this problem, I am planing to check the version before execution of module. For this, I have tried callback method to check ansible version. I have observed that callback works as expected if there is no error in the ansible play book.

Can it be possible to guide me on this to write a sample snippet which executes before play book execution starts. Also wanted to make sure this check will execute only once per host.

Thanks in advance.

Thanks & Regards,
Vinod Kumar

Hi Vinod,

I don’t quite understand your use case - only the Ansible version on the controller that you run the playbook from matters; Ansible runs commands by SSH on the nodes you manage with it, and at that point sends them executable scripts that don’t need any Ansible-specific packages installed to run.

That said, grabbing the version of an installed package on a system and evaluating it to decide whether a playbook should continue is useful. I don’t think Ansible version is in the info Ansible collects about hosts in its inventory when it gathers facts. So I’d do something like include a playbook above the one you only want to run on 2.3+ which contains something like this:

`

  • name: Check Ansible versions.
    `
    hosts: all

tasks:

  • name: Gather ansible version
    command: ansible --version
    register: ansible_version

  • name: Display the info you have gathered
    debug: var=ansible_version

  • name: stop execution if the ansible version is lower than 2.3
    fail: msg=“Please upgrade to Ansible 2.3 or higher”
    when: ansible_version.full < 2.3

This will grab the current version, then stop execution against that host and mark the host failed if the version is under 2.3.

Best,
Nikki

Thanks Nikki for your inputs. Apologies if I am unable to explain the problem correctly. Let me put in short words:

  1. I am using ansible 2.3.1 version and designed my playbooks (used ‘tempfile’ resource which starts supporting from this version).They are working as expected in development environment.
  2. In one of our environment, we are also using ansible 2.2.1 version as server. In that environment, ansible execution fails as we are using the resource which is not supported.

To avoid the problem, wanted to check is there any way to check what is the version of ansible server we are using (in any environment) before executing the playbook. If so, we can halt the execution instead of compiling and throwing the error.

Thanks & Regards,
Vinod Kumar

Sure! Well the example playbook I posted will do that, it’s just that I feel like the proper solution is to standardise Ansible versions across your different control servers and save yourself from ever hitting this issue again. I realise that’s sometimes easier said than done though! :slight_smile:

HI guys!

I’m using that snippet to see if the local ansible is in the allowed range of versions (some time ago ansible has been updated to 2.3 without our knowledge and because of that our prod deployment failed)

  tasks:
    - name: Check for Ansible version
      assert:
        that:
          - "ansible_version.full in ansible_supported_versions"
        msg: 'Ansible version {{ ansible_version.full }} is not supported! It needs to be one of [{{ ansible_supported_versions | join(", ") }}]!'
      run_once: true
      when: check_ansible_version | bool

And in group_vars:

check_ansible_version: true
ansible_supported_versions:
  - 2.2.3.0
  - 2.2.2.0
  - 2.2.1.0

Best,
Karol

Sorry to bring back such an old post, but I’m experiencing the same issue. From what I can tell, the ansible parser will fail in cases where syntax has changed or new syntax has been introduced (like the move away from include in 2.4.0), causing the logic you provided to never be run. I also went down the callback plugin route without success due to this.

For instance, when using Ansible 2.3.0 I get:

ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.

The error appears to have been in ‘/Users/xyz/tmp/directories/main.yml’: line 29, column 3, but may

be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  • include_tasks: thing.yml

^ here

Ansible failed to complete successfully. Any error output should be

visible above. Please fix these errors and try again.

Is there another approach to this? From what I can tell, everything is iteratively parsed (for good reason) before beginning to take action and making the callback plugin, playbook version checking logic, etc. relevant.

Jon

My callback function attempt in more detail:

  1. Write and implement a callback plugin that fails if you are using ansible < 2.4.0 (similar to this).
  2. Run “Hello world” playbook with ansible 2.3.0.
  3. Callback plugin properly detects the version of ansible and fails as expected (i.e. plugin works).
  4. Run a playbook with syntax not yet supported in 2.3.0 (include_tasks, for instance).
  5. Encounter the “no action detected in task” error.
  6. Upgrade to ansible 2.6.3.
  7. Run playbook with syntax not yet supported in 2.3.0.
  8. Succeeds, as expected.
    I believe this is related - https://github.com/ansible/ansible/issues/18375 - but I’m unclear on how https://github.com/openshift/openshift-ansible/pull/2942 is working unless there’s some way to segment the syntax checking so it succeeds and runs the callback plugin prior to encountering any more complicated playbooks?

Jon