If you are not familiar with modules, check out Ansible - Getting Started with Modules.
There are a few modules that can be used to manage packages.
- apt module
- dnf module
- package module (this article)
- package_facts module
- yum module
It often make sense to use the ansible.builtin.package module because the package module should be able to be used against any Linux distribution. On the other hand, the other package management modules are can only be used against certain distributions. For example, the dnf module can only be used against Red Hat distributions (CentOS, Fedora, Red Hat).
However, be aware that the ansible.builtin.package module may fail fatal with the following based on the package manager being used on the target server, and the version(s) of Python on the target server.
fatal: [server1.example.com]: FAILED! => {"changed": false, "msg": "The Python 2 yum module is needed for this module. If you require Python 3 support use the `dnf` Ansible module instead."}
What I have found to be most stable is to use the ansible_pkg_mgr fact to determine if the package manager being used on the target server and to then use the module for the package manager being used on the target server.
---
- hosts: all
tasks:
- name: update wget using dnf
ansible.builtin.dnf:
name: wget
state: latest
when: ansible_pkg_mgr == 'dnf'
- name: update wget using yum
ansible.builtin.yum:
name: wget
state: latest
when: ansible_pkg_mgr == 'yum'
- name: update wget using apt
ansible.builtin.apt:
name: wget
state: latest
when: ansible_pkg_mgr == 'apt'
...
On a Red Hat distributions (CentOS, Fedora, Red Hat), if you need to create a .repo file, such as /etc/yum.repos.d/epel.com, the yum_repository module can be used to create the .repo file.
---
- hosts: all
tasks:
- name: add the /etc/yum.repos.d/epel.repo
ansible.builtin.yum_repository:
name: epel
description: EPEL repo
baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
...
Use list to determine if a package is available or installed
---
- hosts: localhost
tasks:
- name: determine if cifs-utils is available or installed
ansible.builtin.package:
list: cifs-utils
register: out
- ansible.builtin.debug:
var: out
...
Something like this should be returned.
ok: [localhost] => {
"out": {
"changed": false,
"failed": false,
"msg": "",
"results": [
{
"arch": "x86_64",
"epoch": "0",
"name": "cifs-utils",
"nevra": "0:cifs-utils-6.15-1.fc34.x86_64",
"release": "1.fc34",
"repo": "@System",
"version": "6.15",
"yumstate": "installed"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "cifs-utils",
"nevra": "0:cifs-utils-6.15-1.fc34.x86_64",
"release": "1.fc34",
"repo": "updates",
"version": "6.15",
"yumstate": "available"
},
{
"arch": "x86_64",
"epoch": "0",
"name": "cifs-utils",
"nevra": "0:cifs-utils-6.11-3.fc34.x86_64",
"release": "3.fc34",
"repo": "fedora",
"version": "6.11",
"yumstate": "available"
}
]
}
}
Install a package
In this example, if the wget package is not installed on the system, the latest version of wget will be installed. If wget is already installed, wget will be updated to to the latest version.
---
- hosts: localhost
tasks:
- name: update wget
ansible.builtin.package:
name: wget
state: latest
...
Or reference an RPM.
---
- hosts: localhost
tasks:
- ansible.builtin.package:
name: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
state: present
...
Better yet, the follow can be used to determine if the package is installed and only install if the package is not currently installed.
---
- hosts: all
tasks:
- name: determine if git is installed
ansible.builtin.package:
list: git
register: out
- name: by default, lets set git_installation_status to unknown
ansible.builtin.set_fact:
git_installation_status: 'unknown'
- name: set_fact git_installation_status to 'installed' if the git package is already installed
ansible.builtin.set_fact:
git_installation_status: 'installed'
with_items: "{{ out.results }}"
when: item.yumstate == 'installed'
- name: install git (if not already installed)
ansible.builtin.package:
name: git
state: latest
when: item != 'installed'
...
Install / Upgrade multiple packages
You could also install or upgrade multiple packages at once, like this.
---
- hosts: localhost
tasks:
- name: update wget and bzip2
ansible.builtin.package:
name: ['wget', 'bzip2']
state: latest
...
Update all packages
The wildcard character can be used to update all installed packages on the managed node.
---
- hosts: localhost
tasks:
- name: update all packages - this is like running the 'dnf update' command
ansible.builtin.package:
name: "*"
state: latest
...
Install a Package Group
The dnf group list command with the -v or --verbose flag will return the availabe and installed package groups, listing the package group name and package group ID in parenthesis.
dnf group list --verbose
Something like this should be returned.
Available Groups:
3D Printing (3d-printing)
Administration Tools (admin-tools)
Audio Production (audio)
Authoring and Publishing (authoring-and-publishing)
C Development Tools and Libraries (c-development)
Cloud Infrastructure (cloud-infrastructure)
Cloud Management Tools (cloud-management)
Compiz (compiz)
Container Management (container-management)
D Development Tools and Libraries (d-development)
Design Suite (design-suite)
Development Tools (development-tools)
Domain Membership (domain-client)
Fedora Eclipse (eclipse)
The @ characeter is used to install a package group. Here is how you would install the Administration Tools package group.
---
- hosts: localhost
tasks:
- name: install or update the Administration Tools package group
ansible.builtin.package:
name: "@Administration Tools"
state: latest
...
state: absent can be used to uninstall packages.
---
- hosts: localhost
tasks:
- name: remove wget and bzip2
ansible.builtin.package:
name: ['wget', 'bzip2']
state: absent
...
If you want to uninstall a specific version of a package, you will either use a dash after the package name (e.g. kernel-devel-3.10.0-1160.92.1.el7) or equals (e.g. kernel-devel=3.10.0-1160.92.1.el7).
---
- hosts: localhost
tasks:
- name: remove kernel-devel
ansible.builtin.package:
name: kernel-devel-3.10.0-1160.92.1.el7
state: absent
...
Clear DNF cache
The package module does not have an option to clear the cache, which means to remove the files below /var/cache/dnf or /var/cache/yum. If you want to clear the dnf cache, the shell or command modules can be used.
---
- hosts: localhost
tasks:
- name: clear dnf cache
ansible.builtin.command: dnf clean all
...
Did you find this article helpful?
If so, consider buying me a coffee over at