1

Hi friends hope you're being well.

I got this very basic task i need to accomplish via ansible but i'm stuck with variable resiter :

i need to collect some packages version with ansible and display the output as :

host has 'this software : version'

here is the play:

---
    - name: Collect All Package Versions
      hosts: all
      become: yes
      tasks:
        - name: Update APT package cache
          apt:
            update_cache: yes
          become: yes
    - name: Collect Package Versions
      shell: dpkg-query -f '${binary:Package}\t${Version}\n' -W "{{ item }}"
      with_items:
        - firefox
        - libwebp6
        - thunderbird
      register: package_versions

    - name: Display Package Versions
      debug:
        var: package_versions.stdout_lines

When i execute it i got this message:

"package_versions.stdout_lines": "VARIABLE IS NOT DEFINED!"

I know there is a problem with variable registration but i need a little hint.

Thank you ;)

1 Answers1

3

Use the module package_facts. You'll get a dictionary of installed packages in the variable ansible_facts.packages. For example,

    - package_facts:
    - debug:
        msg: "{{ ansible_facts.packages[item]|
                 map(attribute='version') }}"
      loop:
        - firefox
        - libwebp6
        - thunderbird
      when: ansible_facts.packages[item] is defined

gives in Ubuntu

ok: [localhost] => (item=firefox) => 
  msg:
  - 88.0.1+build1-0ubuntu0.20.04.2
ok: [localhost] => (item=libwebp6) => 
  msg:
  - 0.6.1-2
ok: [localhost] => (item=thunderbird) => 
  msg:
  - 1:78.8.1+build1-0ubuntu0.20.04.1

The results are lists because more versions of a package might be installed. If you want to take the first items add the filter first to the pipe

    - debug:
        msg: "{{ ansible_facts.packages[item]|
                 map(attribute='version')|first }}"
      ...

If you put the list of the packages into a variable. For example,

  packages: [firefox, libwebp6, thunderbird]

you can declare the dictionary package_versions

  package_versions: "{{ dict(packages|
                             zip(packages|
                                 map('extract', ansible_facts.packages)|
                                 map('map', attribute='version'))) }}"

gives

  package_versions:
    firefox:
    - 88.0.1+build1-0ubuntu0.20.04.2
    libwebp6:
    - 0.6.1-2
    thunderbird:
    - 1:78.8.1+build1-0ubuntu0.20.04.1

Example of a complete playbook for testing

- hosts: localhost

vars:

packages: [firefox, libwebp6, thunderbird]

package_versions: "{{ dict(packages|
                           zip(packages|
                               map('extract', ansible_facts.packages)|
                               map('map', attribute='version'))) }}"

tasks:

- package_facts:

- debug:
    msg: "{{ ansible_facts.packages[item]|
             map(attribute='version')|first }}"
  loop:
    - firefox
    - libwebp6
    - thunderbird
  when: ansible_facts.packages[item] is defined

- debug:
    var: package_versions