2
votes

We have designed an ansible playbook for nodes on which Ubuntu is installed.

Now we have to play the same Playbook on new machines (node) for a different customer who uses Centos.

The problem is that for Centos, Ansible uses Yum module (which use yum package manager to install module). In our actual playbook, we are obviously using apt module.

What is recommended by Ansible to better manage this scenario?

  • Is it better to rewrite a version of the playbook for Centos?
  • Or is it better to keep the same playbook and use dynamically either "apt" on Ubuntu? or Yum on centos?
  • Is there another more suitable solution?
2

2 Answers

3
votes

A common approach is writing one playbook for multiple distros with a number of conditions inside the playbook or just separate distro-specific tasks into different files and include these files into the main role like this

# Perform distro-specific tasks.
- include_tasks: setup-"{{ ansible_distribution }}".yml

Thus in files setup-Ubuntu.yml, setup-CentOS.yml etc you will keep all the actions specific to a particular Linux. Please also see Geerlingguy's roles like this one as a suitable example.

In the case you want just install or remove a package without using more sophisticated abilities from apt or yum, you may use package module which is rather simple but if thats enough for you then you will get the same code for different Linux flavours.

Also, you need to take into account that in Ubuntu and CentOS many files (including configuration files and program binaries) are located in different places. So if you decide to work with the package module, you may deal with distro-specific things by using external files in a manner like this:

- name: Load a variable file based on the OS type, or a default if not found.
  include_vars: "{{ item }}"
  with_first_found:
    - "{{ ansible_distribution }}-vars.yaml"
    - "{{ ansible_os_family }}-vars.yaml"
    - default-vars.yaml

After this task, you can use variables defined in the mentioned files initialised with values specific to your platform like this

- name: Apply some config template
  template:
    src: my_config_template.j2
    dest: "{{ distro_specific_destination }}"
    validate: "{{ distro_specific_command }} %s"
2
votes

The problem is that for Centos, Ansible uses Yum module (wich use yum package manager to install module). In our actual playbook, we are obviously using apt module.

You'd probably be better off using the package module, which will select an appropriate package manager appropriate to the target machine. Then you just need to maintain per-distribution lists of package names, but the tasks themselves can be identical.

That is, you could write something like:

- hosts: all
  tasks:
    - name: Set OS distribution dependent variables
      include_vars: "os_{{ ansible_facts['distribution'] }}.yml"

    - name: install required packages
      package:
        name: "{{ required_packages }}"
        state: installed

And adjacent to your playbook have, have the files os_Ubuntu.yml and os_CentOS.yml, and in those files set the required_packages variable.