DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

koh-sh
koh-sh

Posted on

How to do "if a package is installed, do something" with Ansible

When you create Playbook, sometimes you may want to do these kinds of tasks.

  • if a package is installed, do something
  • if a user exists, do something

To only check the existence of packages or users without actually installing them.
For this kind of task, command or shell modules works fine.

  tasks:
    - name: check if httpd is installed
      shell: rpm -qa | grep httpd
      register: httpd_installed
      ignore_errors: True
      check_mode: False
      changed_when: False

    - name: print
      debug:
        msg: "httpd is installed"
      when: httpd_installed.rc == 0
Enter fullscreen mode Exit fullscreen mode

But this is a little bit of trouble when you use it many times.

  • Extra parameters like changed_when or ignore_errors should be set
  • Warnings may be thrown at running Playbook or ansible-lint

So this article introduces some modules which can replace your command modules and make your Playbook simpler.

Test Environment

ansible: v2.9.9

targetOS: CentOS7.7 and Ubuntu 18.04

stat

https://docs.ansible.com/ansible/latest/modules/stat_module.html

stat module gets info of files.
Not only existence, it also checks file type(file/directory/link) or owner/group etc.

  tasks:
    - name: check if /etc/hosts exists
      stat:
        path: /etc/hosts
      register: etchosts

    - name: print
      debug:
        msg: "/etc/hosts exists"
      when: etchosts.stat.exists

    - name: print
      debug:
        msg: "/etc/hosts is directory"
      when: etchosts.stat.isdir # this should be False
Enter fullscreen mode Exit fullscreen mode

package_facts

https://docs.ansible.com/ansible/latest/modules/package_facts_module.html

package_facts module gets installed packages list.
The info is available with ansible_facts.packages

  tasks:
    - name: check packages
      package_facts:
        manager: auto

    - name: print
      debug:
        msg: "Version of NetworkManager is {{ ansible_facts.packages['NetworkManager'][0]['version'] }}"
      when: "'NetworkManager' in ansible_facts.packages"
Enter fullscreen mode Exit fullscreen mode

getent

https://docs.ansible.com/ansible/latest/modules/getent_module.html

getent module is a wrapper of getent command and can get info from passwd or group.
The info is available with getent_*** (*** is the name of database)
*Available databases varies on each OS and version.

  tasks:
    - name: check users
      getent:
        database: passwd

    - name: print
      debug:
        msg: "app1 user exists"
      when: "'app1' in getent_passwd"
Enter fullscreen mode Exit fullscreen mode

service_facts

https://docs.ansible.com/ansible/latest/modules/service_facts_module.html

service_facts module get services list.
The info is available with ansible_facts.services

  tasks:
    - name: check services
      service_facts:

    - name: print
      debug:
        msg: "firewalld is {{ ansible_facts.services['firewalld.service']['status'] }}"
      when: "'firewalld.service' in ansible_facts.services"
Enter fullscreen mode Exit fullscreen mode

Conclusion

By using each module instead of command module makes your Playbooks simpler and more useful for multiple OSs.

Top comments (0)

12 Rarely Used Javascript APIs You Need

Practical examples of some unique Javascript APIs that beautifully demonstrate a practical use-case.