DEV Community

Arseny Zinchenko
Arseny Zinchenko

Posted on • Originally published at rtfm.co.ua on

Ansible: check if a package is installed on a remote system

Have a self-written letsencrypt role (see the Prometheus: RTFM blog monitoring set up with Ansible – Grafana, Loki, and promtail post).

Before running the Let’s Encrypt client to obtain a new certificate – need to check if NGINX is installed on a remote host.

Let’s use the package_facts module:

...
- name: "Check if NGINX is installed"
  package_facts:
    manager: "auto"
...

And add a conditional check with when using the ansible_facts.packages array:

...
- name: "NGINX test result"
  debug: 
    msg: "NGINX found"
  when: "'nginx' in ansible_facts.packages"

- name: "NGINX test result"
  debug: 
    msg: "NGINX NOT found"
  when: "'nginx' not in ansible_facts.packages"

Check:

...
TASK [test : Check if NGINX is installed] ****
ok: [ssh.dev.rtfm.co.ua]

TASK [test : NGINX test result] ****
ok: [ssh.dev.rtfm.co.ua] => {
  "msg": "NGINX found"
}

TASK [test : NGINX test result] ****
skipping: [ssh.dev.rtfm.co.ua]

PLAY RECAP ****
ssh.dev.rtfm.co.ua      : ok=3    changed=0    unreachable=0    failed=0
...

Remove NGINX:

root@rtfm-do-dev:~# apt purge nginx

Run again:

...
TASK [test : Check if NGINX is installed] ****
ok: [ssh.dev.rtfm.co.ua]

TASK [test : NGINX test result] ****
skipping: [ssh.dev.rtfm.co.ua]

TASK [test : NGINX test result] ****
ok: [ssh.dev.rtfm.co.ua] => {
  "msg": "NGINX NOT found"
}

PLAY RECAP ****

ssh.dev.rtfm.co.ua      : ok=3    changed=0    unreachable=0    failed=0

Done.

Similar posts

Oldest comments (3)

Collapse
 
jeffersfp profile image
Jefferson Pires

Hey man! Which version of Ansible are you using? I'm using 2.8 and the packages key of facts are not being filled in :( I'm getting an empty dict {}.

Collapse
 
pfuntner profile image
John Pfuntner • Edited

Nice! I came up with a playbook that has a single debug task:

$ cat is-package-installed.yml
- name: Check to see if a package is installed
  hosts: "{{ hosts | default('localhost') }}"
  tasks:

  - name: Gather the packager facts
    package_facts:

  - name: Package status
    debug:
      msg: "{{ item }} {{ 'installed' if item in ansible_facts.packages else 'not installed' }}"
    loop: "{{ pkgs | default([]) }}"
$ ansible-playbook -e '{ "pkgs": ["foo", "zip"] }' is-package-installed.yml

PLAY [Check to see if a package is installed] ***********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Gather the packager facts] ************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Package status] ***********************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=foo) => {
    "msg": "foo not installed"
}
ok: [localhost] => (item=zip) => {
    "msg": "zip installed"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$
Collapse
 
pfuntner profile image
John Pfuntner

Be aware of this requirement for the the package_facts module:

For Debian-based systems python-apt package must be installed on targeted hosts.

Otherwise, ansible_facts.packages is an empty dictionary. Reminder: Ubuntu is Debian-based.