'Best way to check for installed yum package/rpm version in Ansible and use it

I've been getting my feet wet with Ansible (2.0.0.2) on CentOS 7. I'm trying to obtain a version from an installed rpm/yum package, but ran into a warning message when running the script.

Ansible script:

---
- name: Get version of RPM
  shell: yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1
  register: version
  changed_when: False

- name: Update some file with version
  lineinfile:
    dest: /opt/version.xml
    regexp: "<version>"
    line: "  <version>{{ version.stdout }}</version>"

Running this works fine and does what it's supposed to, but it's returning a warning after it executes:

ok: [default] => {"changed": false, "cmd": "yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1", "delta": "0:00:00.255406", "end": "2016-05-17 23:11:54.998838", "rc": 0, "start": "2016-05-17 23:11:54.743432", "stderr": "", "stdout": "3.10.2", "stdout_lines": ["3.10.2"], "warnings": ["Consider using yum module rather than running yum"]}

[WARNING]: Consider using yum module rather than running yum

I looked up information for the yum module on the Ansible site, but I don't really want to install/update/delete anything.

I could simply ignore it or suppress it, but I was curious if there was a better way?



Solution 1:[1]

The way you do it is perfectly fine. The check which is causing the warning is very simply and just checks the first word against a pre-defined list. It ignores further options and often results in warnings which can not be solved with the corresponding module, like in the yum case.

To get rid of the warning you can simply do a which:

shell: `which yum` list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1

which looks up the the complete path of yum, which then is executed. It's the exact same thing, but from viewpoint of Ansible it calls which, not yum which avoids the warning.

If you want to deactivate this kind of warnings globally you can set command_warnings = False in your ansible.cfg. (See docs)

According to the docs you can also add warn=no at the end of your command but this really looks strange to me as it appears to be part of the command.

Solution 2:[2]

I just want to update this old discussion to point out that there is now a package module that makes this more straightforward

- name: get the rpm or apt package facts
  package_facts:
    manager: "auto"

- name: show apache2 version
  debug: var=ansible_facts.packages.apache2[0].version

Solution 3:[3]

I think more native ansible way would be:

- name: get package version
  yum:
    list: package_name
  register: package_name_version

- name: set package version
  set_fact:
    package_name_version: "{{ package_name_version.results|selectattr('yumstate','equalto','installed')|map(attribute='version')|list|first }}"

Solution 4:[4]

How about you use RPM to retrieve the version directly in stead of going trough various pipes:

rpm -q --qf "%{VERSION}" custom-rpm

Solution 5:[5]

It's okay to suppress this warning in your case. Use args like:

---
- name: Get version of RPM
  shell: yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1
  register: version
  changed_when: False
  args:
    warn: no

Equivalent to warn=no on the shell: line but tidier.

Solution 6:[6]

I didn't like any of these answers.

  - name: use command to pull version
    command: '/usr/bin/rpm -qa custom-rpm --queryformat %{VERSION}'
    register: version
    ignore_warnings: True
    changed_when: False

Solution 7:[7]

use the YUM module as suggested. This really helps. You need not do any installation/update/delete. More over this gives you more options like if the package is already installed it would just ignore it.

Solution 8:[8]

Varaint of peaxol answer setting a fact with the installed package version number for futher tests


- name: Find if custom_rpm is installed
  yum:
    list: custom_rpm
  register: custom_rpm_yum_packages
  when: ansible_os_family == "RedHat"

- name: Extract custom_rpm actual installed version
  set_fact:
     actual_custom_rpm_version:  "{{custom_rpm_yum_packages|json_query(jsonquery)}}"
  vars:
     jsonquery: "results[?yumstate=='installed'].version"
  when: ansible_os_family == "RedHat"

- debug:
    var: actual_custom_rpm_version

Solution 9:[9]

As mentioned by others, you can use the shell command. I found this answer useful for using the ansible yum module instead of the shell command as recommended by the ansible warning: How can I get the installed YUM packages with Ansible?

Summarizing it here for easy reference: You can use yum list from the native yum module in ansible.

- hosts: localhost
  tasks:
    - name: Get installed packages
      sudo: yes
      yum:  list=installed
      register: yum_packages
      changed_when: False

To view the contents of yum_packages:

    - debug:
        var: yum_packages

yum_packages contains a list of all installed packages.

You can then get the version of package of interest by:

- debug: var=item
  with_items: "{{yum_packages|json_query(jsonquery)}}"
  vars:
    jsonquery: "results[?name=='tar'].version"

Please note that jsonquery is only available from ansible 2.2 onwards.

Solution 10:[10]

Try adding the ignore_errors option to handle this. See the Error Handing page for details and examples

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3
Solution 4 Johan Godfried
Solution 5 Steve Kehlet
Solution 6 Jacob Evans
Solution 7 Aprameya NDS
Solution 8 Sylvain
Solution 9 Janfy
Solution 10 dan_linder