Importing the variable files based on the OS family in the Ansible Playbook
By: Ankush Chavan
Tags: Redhat Linux, Ansible, Operating Systems, Automation, Configuration Management

When we are solving the real-world use cases we may encounter the problems where we want to write a code once and that code should run across all of the Operating Systems. But there are certain things that are OS-specific like the software packages names, some command names, or anything else. Taking Ansible automation into consideration, we can easily solve this problem by creating separate variables files for each family of the OS.

But the next problem is how do we import these files?

The possible answer is we can write some condition checkings. But it’s a bad approach when ansible is providing us a great thing called Ansible Facts. By using Facts with some intelligence we can solve this use case. So in this article, we will talk and see practically how to achieve this.

Let us first know what are Ansible Facts.

With Ansible, we can retrieve certain variables that will have the information about the remote system as well as the Ansible itself. The variables related to the remote system are known as facts. Facts are handy when we have to make certain decisions and have to run certain code on remote systems. Facts can retrieve the information such as the OS Family, the CPU count, Free memory, the Package Manager, etc.

As you know what are Ansible Facts by now, let’s see how we can use these facts in the real scenario step by step.

Step 1: Creating the variable files for different OS families

The first step we have to do is to figure out what are those things are OS-specific.

For the sake of this article, let’s assume we want to install the apache web server on the RedHat and Ubuntu Operating Systems.

If we look for the software for an apache web server, we get to know that the software name for the RedHat OS and Ubuntu OS is different. For RedHat the software name is httpd and for Ubuntu the name is apache2.

The RedHat OS comes under the RedHat OS family and the Ubuntu OS comes under the Debian OS family.

So, we have to create the variable files with the name of the OS families because later in the playbook, we will use one of the property/variable from the ansible facts that will retrieve the OS family.

So, let’s go and create a variable file for RedHat OS with the name RedHat.yml

$ vim RedHat.yml

Create one variable inside this file and provide the software name to it.

Now, onwards, when we create the variable files for other OS families, the variable name for the package will be the same as this file, that is the packageName.

Similarly, create a variable file for Ubuntu OS named Debian.yml.

$ vim Debian.yml

Now, we have our variable files ready.

Step 2: Create an Ansible Playbook to use these variable files with intelligence

The code for the ansible-playbook named dynamicOS.yml will look like this

This playbook will run on all of the hosts of the dynamicOS group in the ansible inventory.

The Ansible facts provide us one variable named ansible_os_family. This variable contains the name of the family of the remote OS. As we already had named the variable file with the OS family names, we just have to add the .yml file extension at the end of the OS family name retrieved by the ansible_os_family variable using string interpolation. This will import the appropriate variable file.

As we had used a constant variable for the software name for every variable file that is the packageName, we will use this variable to get the package name and provide it to the package module in the ansible to install it.

As the variable files are imported with the intelligence, the packageName variable will get the httpd value when the OS Family is RedHat and apache2 value when the OS Family is Debian.

Let’s see it in action.

Step 3: Run the playbook on RedHat OS

For running the playbook on the RedHat OS, we have to add the IP of the RedHat OS to the dynamicOS group in the inventory.

Let’s ping to this RedHat OS to make sure it is accessible to the Ansible.

$ ansible dynamicOS -m ping

Now, run the playbook on the dynamicOS host group that has the IP of the RedHat OS.

$ ansible-playbook dynamicOS.yml

The playbook had executed successfully. That means it had picked up the right variable file for the RedHat OS and installed the apache web server with the httpd software.

Let’s go to the managed node and confirm if the httpd package is installed.

The above image shows that the httpd software is installed successfully.

Step 4: Run the playbook on the Ubuntu OS

Similar to step 3, go to the inventory file and remove the RedHat OS IP and add the IP of the Ubuntu OS.

Let’s check if ansible can ping the Ubuntu OS.

Ansible is able to ping the Ubuntu OS successfully.

Now, run the same playbook on the dynamicOS host group in the ansible inventory that has the IP of the Ubuntu OS.

You can see in the above image that the playbook had executed successfully. This means it had picked up the right variable file that is the Debian.yml file and installed the apache2 software in the Ubuntu OS.

We can check the same by going to the managed node and check if ansible software is installed.

You can see in the above image that the apache2 software is installed successfully.

So, finally, we had achieved our goal to import and use the OS-specific variable file in the Ansible Playbook.