How can I check if a software package is installed on a Linux system using Ansible?. You can use Ansible automation tool to query installation status of a package on Linux a system. From the results a condition can then be used, e.g skip a task if package is installed, or install if check status is failed.
We’ll have two test scenarios.
- Check if package is installed and output status in the results message
- Execute another task based on the check results.
We will be checking if vim package is installed on either Debian based or Red Hat based Linux distribution.
Using Ansible command module
Create a new playbook file called check_package.yml
vim check_package.yml
Here are the contents of the file.
---
- hosts: servers
#connection: local # When running locally
vars:
package_names:
- vim
tasks:
- name: "Check if listed package is installed or not on Debian Linux family"
command: dpkg-query -l "{{ item }}"
loop: "{{ package_names }}"
register: package_check
when: ansible_facts['os_family'] == "Debian"
- name: "Check if listed package is installed or not on Red Hat Linux family"
command: rpm -q "{{ item }}"
loop: "{{ package_names }}"
register: package_check
when: ansible_facts['os_family'] == "RedHat"
- name: "Print execution results"
debug:
msg: "Package is installed"
when: package_check is succeeded
Create a hosts inventory file:
$ vim hosts
[all:vars]
ansible_user='root' #change accordingly
ansible_become=yes
ansible_become_method=sudo
[servers]
10.10.10.11
10.10.10.12
Validate Playbook syntax:
$ ansible-playbook --syntax-check check_package.yml -i hosts
playbook: check_package.yml
Run the playbook:
$ ansible-playbook -i hosts check_package.yml
PLAY [servers] ***************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [server1]
ok: [server2]
TASK [Check if vim package is installed or not on Debian Linux family] *******************************************************************************************
changed: [server1] => (item=vim)
changed: [server2] => (item=vim)
TASK [Check if vim package is installed or not on Red Hat Linux family] ******************************************************************************************
skipping: [server1] => (item=vim)
skipping: [server2] => (item=vim)
TASK [Print executaion results] **********************************************************************************************************************************
ok: [server1] => {
"msg": "Package is installed"
}
ok: [server2] => {
"msg": "Package is installed"
}
PLAY RECAP *******************************************************************************************************************************************************
server1 : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
server2 : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Using Ansible package module
The same results can be achieved using package module. Below is the modified playbook using package module.
$ vim check_package1.yml
---
- hosts: servers
#connection: local # When running locally
vars:
package_names:
- vim
- telnet
tasks:
- name: "Check if listed package is installed or not on Debian Linux family"
ansible.builtin.package:
name: "{{ item }}"
state: present
check_mode: true
loop: "{{ package_names }}"
register: package_check
- name: "Print execution results"
debug:
msg: "Package is installed"
when: package_check is succeeded
Execution:
$ ansible-playbook -i hosts check_package1.yml
PLAY [servers] ***************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [server1]
ok: [server2]
TASK [Check if vim package is installed or not on Debian Linux family] *******************************************************************************************
ok: [server1] => (item=vim)
ok: [server1] => (item=telnet)
changed: [server2] => (item=vim)
changed: [server2] => (item=telnet)
TASK [Print execution results] ***********************************************************************************************************************************
ok: [server1] => {
"msg": "Package is installed"
}
ok: [server2] => {
"msg": "Package is installed"
}
PLAY RECAP *******************************************************************************************************************************************************
server1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server2 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run a task based on results outcome
Let’s modify the playbook to check if packages are present locally in the system, if not install them.
$ vim check_package.yml
---
- hosts: servers
#connection: local # When running locally
remote_user: root
vars:
package_names:
- nano
- vim
tasks:
- name: "Check if listed package is installed or not on Debian Linux family"
command: dpkg-query -l "{{ item }}"
loop: "{{ package_names }}"
register: debian_package_check
when: ansible_facts['os_family'] == "Debian"
- name: "Check if listed package is installed or not on Red Hat Linux family"
command: rpm -q "{{ item }}"
loop: "{{ package_names }}"
register: redhat_package_check
changed_when: false
ignore_errors: true
when: ansible_facts['os_family'] == "RedHat"
- name: Install package if not present Debian
ansible.builtin.package:
name: "{{ item }}"
state: present
loop: "{{ package_names }}"
when: debian_package_check is failed and ansible_facts['os_family'] == "Debian"
- name: Install package if not present RedHat
ansible.builtin.package:
name: "{{ item }}"
state: present
loop: "{{ package_names }}"
when: redhat_package_check is failed and ansible_facts['os_family'] == "RedHat"
Sample execution:
$ ansible-playbook -i hosts check_package.yml
PLAY [servers] ***************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [server1]
ok: [server2]
TASK [Check if vim package is installed or not on Debian Linux family] *******************************************************************************************
skipping: [server2] => (item=nano)
changed: [server1] => (item=nano)
TASK [Check if vim package is installed or not on Red Hat Linux family] ******************************************************************************************
skipping: [server1] => (item=nano)
failed: [server2] (item=nano) => {"ansible_loop_var": "item", "changed": false, "cmd": ["rpm", "-q", "nano"], "delta": "0:00:00.014446", "end": "2021-03-25 23:06:14.220052", "item": "nano", "msg": "non-zero return code", "rc": 1, "start": "2021-03-25 23:06:14.205606", "stderr": "", "stderr_lines": [], "stdout": "package nano is not installed", "stdout_lines": ["package nano is not installed"]}
...ignoring
TASK [Install package if not present Debian] *********************************************************************************************************************
skipping: [server1] => (item=nano)
skipping: [server2] => (item=nano)
TASK [Install package if not present RedHat] *********************************************************************************************************************
skipping: [server1] => (item=nano)
changed: [server2] => (item=nano)
PLAY RECAP *******************************************************************************************************************************************************
server1 : ok=2 changed=1 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
server2 : ok=3 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=1
The Playbook could need improvement to work on all Linux distributions. We just demonstrated how package checking if installed on Red Hat and Debian based system can be done.
More guides on Ansible: