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.
- ---
- - name: Display Database Setup and variables
- hosts: DBServerGroup
- become: yes
- gather_facts: False
- vars:
- dbName: myFirstDB
- dbUser: admin
- dbPassword: '12345'
- tasks:
- - name: Install Mariadb and other tools
- yum:
- name: "{{item}}"
- state: present
- loop:
- - mariadb-server
- - MySQL-python
- - unzip
- - git
- - wget
- - name: Add list of users
- user:
- name: "{{item}}"
- state: present
- loop:
- - amit
- - ankit
- - sumit
- - rohit
- - name: Start and Enable Mariadb service
- service:
- name: mariadb
- state: started
- enabled: yes
- - name: Create a new database with name "myFirstDB"
- mysql_db:
- name: "{{dbName}}"
- state: present
- - name: Create user in database with name "admin"
- mysql_user:
- name: "{{dbUser}}"
- password: "{{dbPassword}}"
- priv: '*.*:ALL'
- state: present
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
OUTPUT
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: Display Database Setip and variables
- hosts: DBServerGroup
- become: yes
- gather_facts: False
- tasks:
- - name: Install Mariadb and other tools
- yum:
- name: "{{item}}"
- state: present
- loop:
- - mariadb-server
- - MySQL-python
- - unzip
- - git
- - wget
- - name: Add list of users
- user:
- name: "{{item}}"
- state: present
- loop:
- - amit
- - ankit
- - sumit
- - rohit
- - name: Start and Enable Mariadb service
- service:
- name: mariadb
- state: started
- enabled: yes
- - name: Create a new database with name "myFirstDB"
- mysql_db:
- name: "{{dbName}}"
- state: present
- - name: Create user in database 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, then 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/ WebServersGroup
with the same variable names but different values to show you the precedence.
Now let’s run the playbook to see the variable 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.
For that, we will make a new directory with the below command.
Then create a new file with the web server name
And add the below code.
- userName: webServer3User
- Comment: Variable from host_vars file
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.
Great... 😊 we got the right results with correct precedence.
Case 5 - Overwriting variables with command-line arguments
And again, we can overwrite the variables through thecommand line using -e option
- ansible-playbook precedence.yml -e userName=CommandUser -e Comment=CreatedUsingCommandLine
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.
Summary
In this article, we have learned and seen some cool practical examples of variables and their order of precedence. In the next article in this series, we will be learning some more concepts.
I hope you find this article helpful. Stay tuned for more … Cheers!!
You can also check out some of my previous articles of the series “Learning Ansible” here,