CentOS Alternatives: Migrating Workloads From CentOS To OpenSUSE Leap – Automating With Ansible Part 1

Share
Share

In this blog posts, we’ll dive into adapting your Ansible code made for CentOS to openSUSE Leap, ensuring seamless compatibility. In this first part, we’ll provide advice and a general introduction to ease your way into the process. Then, for the second part, where we’ll delve into practical examples of troubleshooting and adapting existing roles.

Together, we’ll navigate the challenges and rediscover the freedom of choice by making your playbooks OS-agnostic.

 

Understanding Ansible

Ansible is a suite of tools which allows you to define the state of your systems as well as execute remote tasks on them. It typically will execute a playbook that will call Ansible modules and or roles to achieve its purpose. The modules are python scripts that perform different tasks, being OS-agnostic or compatible with different OS depends on the module itself, the same as for indenpotence.

An Ansible playbook is a declarative YAML file that defines a series of tasks, executed in a predefined order, to achieve a desired system state or execute defined actions on target hosts. Playbooks act as orchestration scripts, coordinating the execution of Ansible modules and roles.

An Ansible Role is a modular and reusable unit of automation that encapsulates a specific set of tasks, configurations, and files needed to achieve a well-defined functionality or purpose within a system.

An Ansible Collection is a set of playbooks, roles, modules, plugins and other Ansible content that allows you distribute and organize them easily.

 

What to look for?

When adapting your Ansible playbooks to be used with openSUSE Leap systems we can look at different parts that may need to be adapted, here are some of the most common ones.

 

Package Management

CentOS uses YUM or DNF, although you can use both in openSUSE Leap, by default we will have to install them so to avoid this extra step and at the same time make our playbooks platform agnostic we can use the Ansible module “package” instead of “yum” or “dnf” modules, examples:

Using yum module to install Apache webserver 2.4 or newer:

- name: Install webserver
  ansible.builtin.yum:
    name: httpd>=2.4
    state: present

The same but using “package” module:

- name: Install webserver
  ansible.builtin.package:
    name: apache2>=2.4
    state: present

Please note that some applications may use a different package/s name/s.

 

In the previous example we can see with YUM we install the CentOS Apache package, which is called “httpd”, whilst in the second example, oriented to openSUSE Leap, the package name is called “apache2”. This type of differences in names, and how to overcome them, are covered in more details in our previous blog post “CentOS Alternatives: Migrating Workloads to OpenSUSE Leap – Differences and Similarities”.

 

Service Management

Service names on openSUSE might vary compared to CentOS. We can verify the correct service names for openSUSE and update our playbooks accordingly.

Here another thing to look at is if your playbooks are written using the “systemd” module, which although it will work fine in openSUSE Leap systems, it is a recommended practice to use the OS agnostic “service” module.

 

File Paths and Directories

Filesystem paths on openSUSE adhere to the Filesystem Hierarchy Standard (FHS). Although differences might be minimal, it’s crucial to ensure your playbooks reference the correct file paths for openSUSE, we cover this topic on a previous blog post.

 

Permissions and ownership

Sometimes the ownership and permissions differ, applications may use different users to run or due to security policies the permissions are more restrictive, this is less common but may happen, to avoid issues when using Ansible it’s recommended to leave the permissions and ownership untouched unless we are creating a new configuration file that no longer exists.

 

OS Agnostic playbooks?

We have seen sometimes package or service names are different amongst distributions, there are relatively easy ways to overcome this. First step common to all of them is to use variables in the tasks rather than hardcode the names. The following is an example that will let you indicate the packages you want to install instead of hardcoding them into the playbook.

Original task:

- name: Install web server
  ansible.builtin.package:
    name: apache2>=2.4
    state: present

New task using a variable for the list of packages to install:

- name: Install web server
  ansible.builtin.package:
    name: "{{ websrv_packages }}"
    state: present

We can define this variable “websrv_packages” on the defaults file ( defaults/main.yml ) inside the Ansible Role (recommended) or, if not using a role, in the inventory file for all the hosts:

[all:vars]
websrv_packages = httpd

 

Having done this, we only need to change this variable when the OS of the system we want to manage doesn’t use “httpd” package.

There are different ways to solve this, one is to create a group in the inventory with all the hosts that are openSUSE Leap, this is easy to implement but not dynamic and requires to include every new host in the list manually:

[all:vars]
websrv_packages = httpd

[openSUSEleap]
myhost.mydemo.lab

[openSUSEleap:vars]
websrv_packages = apache2

 

Another way is to use “ansible_distribution” fact, which is gathered by Ansible dynamically.

Please remember “gather_facts” must be set to true in your playbook for Ansible to gather it:

gather_facts: true

 

When using “ansible_distribution” variable Ansible will fill it with the OS name it identifies dynamically on the managed system, in the case of openSUSE Leap, Ansible will fill this variable with the following string:

openSUSE Leap

and in the case of CentOS with:

CentOS

To do this we will have to define a dictionary and also refer to its items in the task.
Below is an example of a task using this variable and the “default” filter, which will let you fall back to the a default value if there is nothing defined in the first place:

…
ansible.builtin.package:
  name: "{{ websrv_packages[ansible_facts['distribution']] | default(websrv_packages['default'], true) }}"
…

 

In the inventory we will define the variables, here are two examples of how to do it both in INI format and in YAML, we can also pass on this variable via other means but this is usually the most convenient way:

  • INI formatted inventory:
[all:vars]
websrv_packages={'default':['httpd','mod_ssl'],'openSUSE Leap':['apache2']}
  • YAML formatted inventory:
all:
  vars:
    websrv_packages:
      default:
      - httpd
      - mod_ssl
      openSUSE Leap:
      - apache2

 

We can apply the same concept to services or any other object whose names differ between CentOS and openSUSE.

As mentioned earlier when choosing Ansible modules, unless there is a specific need for using a particular one, it is a recommended practice to use generic ones, like ‘package’ or ‘service’. But when there is no generic module available or we really need to use a particular one that will only work with a specific OS, you can easily make this OS-agnostic by adding an execute condition in the task.

In the following example will only execute one of the tasks if the OS matches the condition, for that we will add a condition that looks at the distribution Ansible fact of the system where the task will be executed:

- name: Register the system
  block:
  - name: Register to Uyuni
    include_role:
      name: stdevel.uyuni.client
    vars:
      uyuni_server: myuyuni.server.lab
    when: ansible_facts['distribution'] == "openSUSE Leap"

  - name: Register to Satellite.
    redhat_subscription:
      state: present
      activationkey: "{{ key }}"
      org_id: "{{ org }}"
    when: ansible_facts['distribution'] == "CentOS"

Note, this is just an example, Uyuni (the upstream community project from which SUSE Manager is derived) can manage CentOS systems as well as openSUSE and others, so we could be using it for CentOS as well without having two system management platforms for manage our systems.

In summary using variables in tasks that may differ from OS to OS and using generic Ansible modules rather than specific will grant you more freedom of choice when it comes to OS and reusability of your automation.

 

Conclusion:

Adapting Ansible playbooks for openSUSE Leap and/or making them OS-agnostic allows you to harness the full potential of automation in your Linux environment. By adopting these practices and understanding the differences in package names, service management, file paths, and system configuration, you can adapt your playbooks seamlessly and create new playbooks, roles or collections that can work with nearly any OS distribution.

The beauty of all this is that you will have freedom of choice without having to reinvent your automation.

As a CentOS alternative, openSUSE brings numerous benefits, including stability, SUSE’s support to the community, powerful system management tools, advanced distro features, and access to a rich package repository. The active openSUSE community and easy migration tools further enhance the transition process. If you are seeking a robust and reliable Linux distribution for your workloads, you should consider openSUSE.

Looking for further insights into what you can achieve by migrating to openSUSE?, check out other blogs in this series:

 


Ready to experience the power and flexibility of openSUSE Leap?

Download openSUSE Leap Now!

Share
(Visited 27 times, 1 visits today)
Avatar photo
5,781 views
Raul Mahiques   Technical Marketing Manager with a focus on Security .