I can easily get it through using shell commands which is not idempotent

You can't really talk about idempotence, when you are querying the current state of a machine.

"Idempontent" means that the task will ensure the machine is in the desired state no matter how many times you run a certain task.

When you query current state, you don't describe the desired state. No matter what you do, what method you use, the term "idempotent" is just not applicable.


Regarding your example, which does not give you results - you have repeated twice the same argument list and the task should fail (it doesn't, which looks like an Ansible quirk).

To get a list of installed packages, you should use:

- name: yum_command 
  yum:
    list=installed
  register: yum_packages

- debug:
    var: yum_packages

It saves a list of dictionaries describing each package to a variable yum_packages.

You can then use a JSON Query Filter to get a single package (tar):

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

to get a result like this:

"item": {
    "arch": "x86_64",
    "epoch": "2",
    "name": "tar",
    "nevra": "2:tar-1.26-31.el7.x86_64",
    "release": "31.el7",
    "repo": "installed",
    "version": "1.26",
    "yumstate": "installed"
}

Or only its version:

- debug: var=item
  with_items: "{{yum_packages|json_query(jsonquery)}}"
  vars:
    jsonquery: "results[?name=='tar'].version"
"item": "1.26"
Answer from Theresa Garcia on Stack Overflow
🌐
Stack Overflow
stackoverflow.com › questions › 71867548 › ansible-yum-list-installed-and-available-packages
Ansible yum list installed and available packages - Stack Overflow
The list parameter is a string, not a list, as pointed by the documentation, so, if you pass something else than the reserved words — installed, updates, available or repos — it will be considered as a packaged and will probably return your nothing. We can also confirm this by Ansible code source, where the list value is considered in an if ..
🌐
GitHub
gist.github.com › goldyfruit › f4f274be3144e6afca69
[ansible] Check via the yum module and a registered value if a package is installed or not · GitHub
- name: Check if rpm is already installed yum: list: my-rpm # If not installed yum_list.results[*].yumstate != installed register: yum_list - name: Conditionally do next thing debug: msg: "Not installed" when: yum_list.results | selectattr("yumstate", "match", "installed") | list | length == 0 · Copy link · Copy Markdown · the package_facts module maybe better for this. - package_facts: {} - when: ansible_facts.packages["mysql57-community-release"] is undefined block: - yum: name: http://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm state: present - yum: {name: mysql-server, state: present} - service: {name: mysqld, state: started, enabled: yes} - shell: grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'; register: result - ....
Discussions

How do I get a list of packages installed on systems? 'ansible -m setup'
https://docs.ansible.com/ansible/latest/modules/yum_module.html - yum: list: installed register: result for apt i guess you need to use the shell module More on reddit.com
🌐 r/ansible
20
5
July 26, 2018
Check via yum module if a particular package is installed
... gather_facts: true ... tasks: - name: "Check if PHP is installed" package_facts: manager: "auto" - name: "PHP is installed check" debug: msg: "PHP is installed" when: "'php' is in ansible_facts.packages" - name: "PHP is not installed check" debug: msg: "PHP is not installed" when: "'php' not in ansible_facts.packages" More on reddit.com
🌐 r/ansible
9
2
May 20, 2020
Ansible packages and Yum modules not listing all install packages
Your "all" parameter doesn't make any sense in this context. Your adhoc code should have every module parameter inside the -a argument's quotes. ansible myhost -i myinventory -b -m yum -a "list=installed"ansible myhost -i myinventory -b -m package_facts -a "manager=rpm strategy=all" You could also try ansible-console to use debug to check if packages are showing up there. ansible-console myhost -i myinventory -b package_facts debug msg={{ansible_facts.packages|count}} Lastly, -b implies become, but doesn't prompt for the become method or password (if required), so you might need to add -K in order for this to work. I was able to find 645 packages via package_facts on my wsl ubuntu image, albeit with a much newer version of Ansible. More on reddit.com
🌐 r/ansible
4
5
February 23, 2022
Best way to check for installed yum package/rpm version in Ansible and use it - Stack Overflow
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. ... --- - name: Get version of RPM shell: yum list installed custom-rpm | grep custom-rpm | awk '{print ... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 4
21

I can easily get it through using shell commands which is not idempotent

You can't really talk about idempotence, when you are querying the current state of a machine.

"Idempontent" means that the task will ensure the machine is in the desired state no matter how many times you run a certain task.

When you query current state, you don't describe the desired state. No matter what you do, what method you use, the term "idempotent" is just not applicable.


Regarding your example, which does not give you results - you have repeated twice the same argument list and the task should fail (it doesn't, which looks like an Ansible quirk).

To get a list of installed packages, you should use:

- name: yum_command 
  yum:
    list=installed
  register: yum_packages

- debug:
    var: yum_packages

It saves a list of dictionaries describing each package to a variable yum_packages.

You can then use a JSON Query Filter to get a single package (tar):

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

to get a result like this:

"item": {
    "arch": "x86_64",
    "epoch": "2",
    "name": "tar",
    "nevra": "2:tar-1.26-31.el7.x86_64",
    "release": "31.el7",
    "repo": "installed",
    "version": "1.26",
    "yumstate": "installed"
}

Or only its version:

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

Since Ansible 2.5, you can also use the package_facts module: it will gather the list of installed packages as Ansible facts.

Example from the CPU:

- name: get the rpm package facts
  package_facts:
    manager: rpm

- name: show them
  debug: var=ansible_facts.packages
🌐
Ansible
docs.ansible.com › ansible › 2.9 › modules › yum_module.html
yum – Manages packages with the yum package manager — Ansible Documentation
yum: list: ansible register: result - name: Install package with multiple repos enabled yum: name: sos enablerepo: "epel,ol7_latest" - name: Install package with multiple repos disabled yum: name: sos disablerepo: "epel,ol7_latest" - name: Install a list of packages yum: name: - nginx - postgresql - postgresql-server state: present - name: Download the nginx package but do not install it yum: name: - nginx state: latest download_only: true
🌐
FreeKB
freekb.net › Article
Ansible - List packages using the yum module
October 6, 2023 - The yum module can be used to determine if a package is available and installed on the managed node (e.g. the target system). This is similar to the yum info command. In this example, the yum module will be used to determine if the httpd package ...
🌐
Ansible
docs.ansible.com › ansible › 9 › collections › ansible › builtin › yum_module.html
ansible.builtin.yum module – Manages packages with the yum package manager — Ansible Community Documentation
December 3, 2024 - - name: Install the latest version of Apache ansible.builtin.yum: name: httpd state: latest - name: Install Apache >= 2.4 ansible.builtin.yum: name: httpd>=2.4 state: present - name: Install a list of packages (suitable replacement for 2.11 loop deprecation warning) ansible.builtin.yum: name: - nginx - postgresql - postgresql-server state: present - name: Install a list of packages with a list variable ansible.builtin.yum: name: "{{ packages }}" vars: packages: - httpd - httpd-tools - name: Remove the Apache package ansible.builtin.yum: name: httpd state: absent - name: Install the latest vers
Find elsewhere
🌐
Reddit
reddit.com › r/ansible › ansible packages and yum modules not listing all install packages
r/ansible on Reddit: Ansible packages and Yum modules not listing all install packages
February 23, 2022 -

I ran into an odd issue. When I run "yum list installed" or "rpm -qa" it lists a few hundred installed packages.

However, when I run these adhoc command or use them in a playbook I get around 16 packages.

ansible -i 'myhost,' -b -m yum -a 'list=installed' all

ansible -i 'myhost,' -b -m package_facts -a 'manager=rpm' all

The controller and target system are running

- CentOS 7.8

- ansible version 2.9.27

- python 2.7.5 ( old, I know )

Could this be a bug in ansible, or perhaps I need to add additional parameters? For the short term, I can use the shell and parse the results, but it's bothering me that ansible it only returning a subset of installed packages.

🌐
Stack Exchange
devops.stackexchange.com › questions › 6404 › how-can-i-check-for-an-installed-packaged-version-on-multiple-linux-hosts
ansible - How can I check for an installed packaged version on multiple linux hosts? - DevOps Stack Exchange
For checking the package version I tried with the following playbook but Ansible doesn't like the syntax: --- - hosts: test2 become: true tasks: - name: Check Hostname command: /usr/bin/hostname - name: Check for package if is installed yum: list: snapd 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 }}"
Top answer
1 of 2
6

Building up on @gary lopez answer to add security and performance.

First you will need to get an actual list of all packages you want to see installed on your final machine, including the default ones that come with the system. I assume that list will be in var yum_rpm

Once you have that, the next step is to get the list of currently installed packages on the machine. To create an actual list we can reuse:

  - name: Get installed packages
    yum:
      list: installed
    register: __yum_packages

  - name: Make installed packages a list of names
    set_fact:
      installed_packages: "{{ __yum_packages.results | map(attribute='name') | list }}"

From there, adding and removing is just a matter of making a difference on lists. The goal here is to avoid looping on the yum module package by package (because it is damn slow and listed as a bad practice on the module documentation page) and to make the install and remove operations in one go.

  - name: align packages on system to expected
    yum:
      name: "{{ item.packages }}"
      state: "{{ item.state }}"
    loop:
      - packages: "{{ yum_rpm | difference(installed_packages) }}"
        state: present
      - packages: "{{ installed_packages | difference(yum_rpm) }}"
        state: absent
    when: item.packages | length > 0

2 of 2
1

In the first task you need to use state: present. You could try this

vars:
  - yum_rpm:
    - tcpdump
    - tmux
    - psacct

tasks:
  - name: "Install all package in our list"
    yum:
      name: "{{ yum_rpm }}"
      state: present
      update_cache: no

  - name: Get packages installed
    yum:
      list: installed
    register: __yum_packages

  - name: "Remove any other unexpected package already installed"
    yum:
      name: "{{ item.name }}"
      state: absent
    with_items: "{{ __yum_packages.results }}"

But I recommend you validate packages to uninstall because you could uninstall some packages required for your OS.

🌐
Ansible
docs.ansible.com › ansible › latest › collections › ansible › builtin › yum_module.html
ansible.builtin.yum module — Ansible Community Documentation
This redirect is part of ansible-core and included in all Ansible installations. In most cases, you can use the short module name yum even without specifying the collections keyword.
🌐
GitHub
github.com › ansible › ansible › issues › 84123
`ansible.builtin.yum:` list always return "repo": "@System" as result · Issue #84123 · ansible/ansible
October 14, 2024 - the result has always "repo": "@System" in every entry despite when running dnf list --installed, the repo varies. for instance: rpm_packages.results entry: { "arch": "noarch", "envra": "0:yum-4.7.0-20.el8.noarch", "epoch": "0", "name": "yum", "nevra": "0:yum-4.7.0-20.el8.noarch", "release": "20.el8", "repo": "@System", "version": "4.7.0", "yumstate": "installed" }
Author   ansible
🌐
Diewufeiyang
diewufeiyang.com › ansible › en › modules › yum_module.html
yum - Manages packages with the yum package manager — Ansible Documentation
March 31, 2019 - yum: list: ansible register: result - name: Install package with multiple repos enabled yum: name: sos enablerepo: "epel,ol7_latest" - name: Install package with multiple repos disabled yum: name: sos disablerepo: "epel,ol7_latest" - name: Install a list of packages yum: name: - nginx - postgresql - postgresql-server state: present
🌐
GitHub
github.com › ansible › ansible › issues › 29534
yum list installed doesn't show source repo · Issue #29534 · ansible/ansible
September 11, 2017 - This issue/PR relates to code supported by the Ansible Engineering Team. labels ... Needs a first human triage before being processed. label ... This issue/PR relates to a bug. and removed bug_report labels ... Hello! Thank you for the bug report, apologies for the lag time. I'm currently working to clean up the yum module's bug backlog. I wanted to comment here that the yum python API to list installed packages returns a list of type RPMInstalledPackage and that data type has no concept of their original yum repository.
Author   ansible
🌐
W3cubDocs
docs.w3cub.com › ansible~2.10 › collections › ansible › builtin › yum_module
Yum – Manages Packages With the Yum Package Manager - Ansible 2.10 - W3cubDocs
The yum module does not support clearing yum cache in an idempotent way, so it was decided not to implement it, the only method is to use command and call the yum command directly, namely “command: yum clean all” https://github.com/ansible/ansible/pull/31450#issuecomment-352889579 · - name: Install the latest version of Apache yum: name: httpd state: latest - name: Install a list of packages (suitable replacement for 2.11 loop deprecation warning) yum: name: - nginx - postgresql - postgresql-server state: present - name: Install a list of packages with a list variable yum: name: "{{ packa
🌐
EDUCBA
educba.com › home › software development › software development tutorials › ansible tutorial › ansible yum module
Ansible Yum Module | Top 16 parameters of Ansible Yum Module
March 3, 2021 - In Ansible, we have many modules that can make your life as an administrator easy by providing you such features that you would have been doing by complex scripts or a bunch of commands. One such module is the Ansible yum module. This module can remove, install, upgrade, downgrade, list packages, or packages groups with the help of YUM package manager on the target remote machines.
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
Toptechskills
toptechskills.com › ansible-tutorials-courses › ansible-yum-module-tutorial-examples
Ansible yum Module Tutorial + Examples | TopTechSkills.com
May 18, 2024 - Ansible’s yum module is used to manage packages with the yum package manager, which is the default on Red Hat based Linux distributions such as Red Hat Enterprise Linux and CentOS. Most systems require root/superuser permissions to manage packages, which means that become: true is required. I recommend always using the update_cache: true parameter when installing ...