Ansible 10

How to load variable dynamically according to os in ansible?

Problem Statement:

Let’s understand the use case of this problem. There will be many cases when some of the package names are different Linux OS distributions. Also, there will be cases that they are different file formats only such as deb or rpm.

To solve this problem, Ansible offers us one module named “include_vars” which loads variables from files dynamically within the task. This module can load the YAML or JSON variables dynamically from a file or directory, recursively during task runtime.

To detect on which operating system we are performing tasks, we can use the “setup” module. This module is automatically called by playbooks to gather useful variables about the remote hosts that can be used in playbook. This module is also available for windows target.

Let’s take an example of installing an Apache web server in CentOS and Ubuntu Linux. We do not want a hard-coded playbook installing a web server for a different distribution, OS, etc.

First, find out which variables setup module offers use by which we can detect remote host distribution, and accordingly we can load the variable file on the fly.

First check, can we connect both the system using the ping module.

Now, we have connectivity to both the servers, we have to get that variable name which gives us a remote host type variable. The setup module gives many variables under the “ansible_distribution” section. so let's see what variable it gives.

Now, we know the distribution name and major version, we will create variables files and give this distribution name and version name to that files. eg: Ubuntu-18.yml, CentOS-8.yml

Also, you can use the os_family variable which gives the os_family of remote hosts.

Create Ubuntu-18.yml file and add the below variables in that file

# Ubuntu-18.yml
package_name: apache2
service_name: apache2
document_root: /var/www/html

Create CentOS-8.yml file and add below variables

# CentOS-8.yml package_name: httpd service_name: httpd document_root: /var/www/html/

# CentOS-8.yml
package_name: httpd
service_name: httpd
document_root: /var/www/html/

Now we have to write a playbook that will install a webserver and read variables dynamically according to distribution type.

Let's first make sure, we are using selecting proper files using ansible facts. so for that, we will use debug module to create a final string.

---
- name: "Install webserver"
hosts: webserver
tasks:
- name: "Test variables"
debug:
msg: "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml"

Run this playbook, $ ansible-playbook main.yml

Now let’s write a playbook that will read the variables according to the OS type of remote host and install the webserver.

---
- name: "Install webserver"
hosts: all
vars_files:
- "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml"

tasks:
- name: "Install the web server"
package:
name: " {{ package_name }}"
state: present

- name: "Create document root directory"
file:
path: "{{document_root }}"
state: directory
recurse: yes
- name: "Create index.htm page in document root"
copy:
content: "<h1> Welcome to {{ ansible_distribution }} server !! </h1>"
dest: "{{ document_root }}/index.html"

- name: "Start the service"
service:
name: "{{ service_name }}"
state: started
- name: "Test the servers"
hosts: localhost
tasks:
- name: "HealthCheck the servers"
uri:
url: "http://{{item}}"
return_content: yes
with_items: "{{ groups['webserver'] }}"
register: output
failed_when: '"Welcome" not in output.content'

The above playbook will install and test our web server is working properly or not.

$ ansible-playbook main.yml

We can test the installation is successful or not using the curl command.

Conclusion:

Thank you…

Visit him: shubhamrasal. me/blog to know more.

DevOps Engineer at Mindbowser Inc| www.shubhamrasal.me

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store