Ansible – In and Out | All About Variables | Precedence | Part 8

Before we discuss variables, why do you think we need variables? Re-usability is one of the most important reasons for using variables in a playbook.

We are going to update the existing playbook show above and we will replace the static values with the variables. We have seen different types of variables like

  • Inventory variables 
  • Fact variables 
  • Loop variables

Playbook Variables

Here, we are going to see Custom variables which we can define inside the playbook. 

Below is the updated playbook code with some custom variables that defined using vars keyword.

#######################db.yml############################################

---
- name: Displays DB setup and Vars
  hosts: dbsrvgrp
  become: yes
  gather_facts: False
  tasks:
    - name: Install MariaDB SVC
      yum:
        name: "{{item}}"
        state: present
      loop:
        - mariadb-server
        - MySQL-python
        - unzip
        - git
        - unzip


    - name: start and enable mariadb SVC
      service:
        name: mariadb
        state: started
        enabled: yes


    - name: Add users
      user:
        name: "{{item}}"
        state: present
      loop:
        - deepak
        - amit
        - eshaan
        - rachit


    - name: create a new database with name "accounts"
      mysql_db:
        name: accounts
        state: present

    - name: create database user with name "admin"
      mysql_user:
        name: admin
        password: 12345
        priv: '*.*:ALL'
        state: present

Output:

So, we can see that the playbook has executed successfully.

Command line Variables

We can also overwrite the variables defined inside the playbook using the command line. Command-line variables have higher priority than playbook variables.

So, let’s create a new database by giving a different name through the command line.

ansible-playbook db.yml -e dbName=mySecondDB

So, we can see, changed=1 means it has created a new database with the name mySecondDB.

Variables in Group_Vars

Variables defined in the Group vars have lower priority than playbook variables. So, let’s create a directory called group_vars and define all our variables there which we just defined in the playbook.

mkdir group_vars  
vim group_vars/all 

and add the below variables.

dbName: myFirstDB  
dbUser: admin  
dbPassword: '12345'

Then, remove the variables defined in the playbook. Below is the updated playbook.

---
- name: Displays DB setup and Vars
  hosts: dbsrvgrp
  become: yes
  gather_facts: False
  tasks:
    - name: Install MariaDB SVC
      yum:
        name: "{{item}}"
        state: present
      loop:
        - mariadb-server
        - MySQL-python
        - unzip
        - git
        - unzip


    - name: start and enable mariadb SVC
      service:
        name: mariadb
        state: started
        enabled: yes


    - name: Add users
      user:
        name: "{{item}}"
        state: present
      loop:
        - deepak
        - amit
        - eshaan
        - rachit


    - name: create a new database with name "accounts"
      mysql_db:
        name: "{{dbName}}"
        state: present


    - name: create database user with name "admin"
      mysql_user:
        name: "{{dbUser}}"
        password: "{{dbpassword}}"
        priv: '*.*:ALL'
        state: present

So, it has executed successfully without any errors.

NOTE
Ansible first looks for variables in the playbook and if not found, it goes and checks the variables if they are defined in the group_vars. If there also, Ansible doesn’t find them, it will give you the error as variables not defined. 
So above, we have seen that our playbook executed successfully, but how do you know from where it has picked the variables as variables can be defined at multiple places?

Variables Precedence with examples

Whenever the module gets executed in ansible it returns the output in JSON format and if we want to keep that JSON output we can use register in playbook.

We can use the ansible module debug to print the value of variables.

Case 1 – Variables defined inside the playbook

In this example below, we have defined two variables username and comment in the playbook. 

We will create a new playbook named precedence.yml and write the below code.

---                                                                                                                                                                                                               
- hosts: all                                                                                                                                                                                                      
  vars:                                                                                                                                                                                                           
    userName: playbookUser                                                                                                                                                                                        
    Comment: User from playbook                                                                                                                                                                                   
  tasks:                                                                                                                                                                                                          
   - name: Create User                                                                                                                                                                                            
     user:                                                                                                                                                                                                        
        name: "{{userName}}"                                                                                                                                                                                      
        comment: "{{Comment}}"                                                                                                                                                                                    
     register: user_output                                                                                                                                                                                        
                                                                                                                                                                                                                  
   - debug:                                                                                                                                                                                                       
        var: user_output                                                                                                                                                                                          

And we can see from the output that user has been added successfully on all servers and debug module has printed user_output variable with the details. To further refine the output, we can add only those keys which we really want to see. So, we will add name and comment in the debug module.

---                                                                                                                           
- hosts: all                                                                                                                  
  vars:                                                                                                                       
    userName: playbookUser                                                                                                    
    Comment: User from playbook                                                                                               
  tasks:                                                                                                                      
   - name: Create User                                                                                                        
     user:                                                                                                                    
        name: "{{userName}}"                                                                                                  
        comment: "{{Comment}}"                                                                                                
     register: user_output                                                                                                    


   - debug:                                                                                                                   
        var: user_output.name                                                                                                 
   - debug:
        var: user_output.comment

We can see now that variables are being used from the playbook with the help of the debug module.

Case 2 – Variables defined inside group_vars/all

Now let’s remove the variables earlier defined in the playbook and define them inside the group_vars/all. Below is the updated group_vars/all file

dbName: myFirstDB  
dbUser: admin  
dbPassword: '12345'  
userName: commonUser  
Comment: user fom group_vars/all file 

And Below is the updated playbook

---                                                                                                                                                                                                               
- hosts: all                                                                                                                                                                                                      
  tasks:                                                                                                                                                                                                          
   - name: Create User                                                                                                                                                                                            
     user:                                                                                                                                                                                                        
        name: "{{userName}}"                                                                                                                                                                                      
        comment: "{{Comment}}"                                                                                                                                                                                    
     register: user_output                                                                                                                                                                                        
                                                                                                                                                                                                                  
   - debug:                                                                                                                                                                                                       
        var: user_output.name                                                                                                                                                                                     
                                                                                                                                                                                                                  
   - debug:                                                                                                                                                                                                       
        var: user_output.comment     

We can see that the variables in the playbook have been picked from the group_vars/all and that can be seen in the output.

Case 3 – Variables defined inside group_vars/groupname

From our existing inventory file, we can see different groups defined. Group vars and Host vars are inventory specific variables. Now suppose we need separate variables for WebServersGroup.
So, I will create a file with the name of a group with the below command.

vim group_vars/websrvgrp

With the same variable names but different values to show you the precedence.

We can see that for the web servers the variables are being taken from the group-specific files while for the Db server it comes from the group_vars/all file. 

Case 4 – Variables defined inside host_vars/hostname

Now suppose for Web Server 03 we need other values of the variables that we have earlier used for the entire group.

mkdir host_vars

Then create a new file with the web server name

vi host_vars/websrv03  

And add the below code.

userName: webServer3User

Now we can see that we have defined the same variables at 3 places with different values.

So, for web server 03 it will pick the value from the host_vars/websrv03 file and for web server 01 and 02 it will pick from group_vars/WebServersGroup and for database server 01 it will pick from group_vars/all file.

Case 5 – Overwriting variables with command-line arguments

And again, we can overwrite the variables through the command line using -e option 

ansible-playbook precedence.yml -e userName=CommandUser

From the output, as the command line variables have the highest precedence, we can see that all our servers have got the values of the variables from the command line.

About the author

Deepak Sood

Deepak Sood is Lead Consultant in an IT firm holding expertise in Devops and QA Architecture with 8 years of experience.

His expertise is in building highly scalable frameworks. His skills include Java, Configuration Management, Containers, and Kubernetes.

Reach out to him using contact form.

View all posts