Anyone who works with configuration management software such as Puppet, Chef or Ansible in heterogeneous Linux environments knows the problem:

If you want to install a certain software, the package names often differ - and also the number of packages.

This article shows a small Playbook for Ansible, with which the package selection can be determined distribution- and version-specific.

In the example we want to install the ftpclient "ncftp", which is not available on SLES, so we use "lftp" here.

The following listing shows the Playbook "install-ftpclient.yml"

- hosts: all
  remote_user: root


  - name: read vars
    include_vars: '{{ item }}'
      - files:
          # "ansible_distribution" may be: "Debian", "SLES", "Ubuntu", "CentOS"
          # "ansible_distribution_version" may be: "9.0", "12.2", "16.04", "7.3.1611"
          # "ansible_distribution_major_version" may be: "9", "12", 16.04"
          # "ansible_os_family" may be: "Debian", "RedHat", "Suse"
          # Upper/lower case is important

          - "{{ ansible_distribution }}.{{ ansible_distribution_version }}.packagenames.yml"
          # results in: "SLES.12.2", "Ubuntu.16.04", "CentOS.7.3.1611", "Debian.8.7"

          - "{{ ansible_distribution }}.{{ ansible_distribution_major_version }}.packagenames.yml"
          # results in: "SLES.12", "Ubuntu.16", "CentOS.7", "Debian.9"

          - "{{ ansible_distribution }}.packagenames.yml"
          # results in: "Debian", "SLES", "Ubuntu", "CentOS"

          - "{{ ansible_os_family }}.packagenames.yml"
          # results in: "Debian", "Suse, "RedHat"

          - "default.packagenames.yml"
        paths: "./vars/"

  - name: install ftpclient
    package: name={{ ftpclient_package_name }} state=installed

Then simply create files of your choice in the"./vars" folder. These are searched for in the order shown above - the first hit is loaded.

This way you can use different files and variables depending on the service pack for distributions where so-called service packs sometimes bring serious changes in the package selection. An example would be here: SLES12SP1 and SLES12SP2.

This is what the file repository looks like:


Contents of the Debian.packagenames.yml:

ftpclient_package_name: ncftp

Contents of the SLES.packagenames.yml:

ftpclient_package_name: lftp

Multiple packages in one variable:

If you need several packages, you can simply specify them one after the other, similar to an array.
There must not be any blanks. The number of packages may be different for each operating system.

vim_package_name: vim,vim-icinga2,vim-syntastic


728# ansible-playbook  install-packages.yml

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [debian8testvm1.local]
ok: [debiantestvm1.local]
ok: [sles12sp2-1.local]
ok: [ubuntu1604testvm1.local]
ok: [centos7-1.local]

TASK [read vars] ******************************************************
ok: [debiantestvm1.local] => (item=/opt/projects/ansible-install-ftpclient/./vars/Debian.packagenames.yml)
ok: [centos7-1.local] => (item=/opt/projects/ansible-install-ftpclient/./vars/CentOS.packagenames.yml)
ok: [sles12sp2-1.local] => (item=/opt/projects/ansible-install-ftpclient/./vars/SLES.12.2.packagenames.yml)
ok: [ubuntu1604testvm1.local] => (item=/opt/projects/ansible-install-ftpclient/./vars/Debian.packagenames.yml)
ok: [debian8testvm1.local] => (item=/opt/projects/ansible-install-ftpclient/./vars/Debian.packagenames.yml)

TASK [install ftpclient] *******************************************************
ok: [centos7-1.local]
ok: [debian8testvm1.local]
ok: [ubuntu1604testvm1.local]
changed: [debiantestvm1.local]
changed: [sles12sp2-1.local]

PLAY RECAP *********************************************************************
centos7-1.local     : ok=3    changed=0    unreachable=0    failed=0
debian8testvm1.local : ok=3    changed=0    unreachable=0    failed=0
debiantestvm1.local  : ok=3    changed=1    unreachable=0    failed=0
sles12sp2-1.local   : ok=3    changed=1    unreachable=0    failed=0
ubuntu1604testvm1.local : ok=3    changed=0    unreachable=0    failed=0

Try it by yourself?

Just clone my sample repository "ansible_install...." on Github.

Translated via: