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.