Contents
UNDERSTANDING THE SUBJECT MATTER
In our previous lesson, we learnt how to create a basic playbook, we also learnt the different indentation levels of plays and tasks in a playbook.
In this lesson, we will learn what variables are, how to add variables to a playbook, and how to reference variables outside of a playbook.
What Are Ansible Variables
Variables are like repositories that hold information and are used to store information that needs to be referenced.
Ansible variables can be declared in various ways, the most important thing is to know how to declare these variables cleverly so that the administration of the network environment can be easy and convenient.
Ansible variables can be defined inside of a playbook at a play level, however, in some cases, this makes the playbook long and difficult to read. The alternative to this is defining the variables outside of the playbook.
There are 22 different ways Ansible variables can be defined and they all have an order of precedence. Click here to see the order of precedence.
As we go on in this course, we will look at how to define variables in some of these 22 ways in the ACTION TIME section below, and we will always refer to the link above for better understanding.
How do you pass variables in Ansible?
A valid variable name constitutes letters, numbers, and the underscore punctuation only or a mixture of the three.
More so, variables can’t have any other punctuation apart from underscore and can’t also start with the underscore punctuation nor with a number.
A variable must start with a letter only and must include two curly brackets at the beginning and the end. More so, when a variable is a value to a key, in other words, when a key’s value begins with a variable, encapsulation is required.
An example of valid variables are shown below
{{ tekneed_variable }}
{{ tekneed_1 }}
{{ tekneed123 }}
An example of invalid variables are shown below
{{ 123tekneed }}
{{ 1_tekneed }}
{{ tek need }}
{{ tek.need }}
{{ tek-need }}
An example of valid variables that are values to keys, i.e, (key-value) pair are shown below
"{{ tekneed_variable }}"
"{{ tekneed_1 }}"
"{{ tekneed123 }}"
In the “ACTION TIME” section below, we will look at the different ways we can define and pass Ansible variables with examples.
ACTION TIME
Step By Step Guide Of How To Use Ansible Variables Example
In our previous lesson, we automated the installation of the httpd service by using an ansible playbook, however without variables. Let’s see how to use variables in the example below.
Example
In this example, as the user, lisa, we will automate the installation of the httpd service still, inclusive of some other packages such as firewalld and autofs but with variables this time around.
In my environment, the inventory file and the ansible configuration file can be seen below.
[lisa@drdev1 ~]$ cat inventory/static-ini-inventory
[group1]
hqdev1.tekneed.com
localhost
[lisa@drdev1 ~]$ cat .ansible.cfg
[defaults]
inventory=/home/lisa/inventory/static-ini-inventory
remote_user=root
ask_pass=false
[privilege_escalation]
become=true
become_user=root
become_method=sudo
beocme_ask_pass=false
Steps
1. create a playbook file
[lisa@drdev1 ~]$ vim my-third-playbook.yml
*add the first play (play name and hosts).
1 ---
2 - name: Packages Installation and deployment
3 hosts: group1
*add the variable name and the variables. The variable name, in this case, is “packages” and the variables are httpd, firewalld and autofs.
1 ---
2 - name: Packages Installation and deployment
3 hosts: group1
4 vars:
5 packages:
6 - httpd
7 - firewalld
8 - auofs
note that this variable is being defined in the playbook at a play level, hence this variable will only work for this play, and in the order of variable precedence, referring to this link, this falls in number 12, which is “play vars”
*add the first task
1 ---
2 - name: Packages installation and deployment
3 hosts: group1
4 vars:
5 packages:
6 - httpd
7 - firewalld
8 - auofs
9 tasks:
10 - name: Install packages
11 yum:
12 name: "{{ packages }}"
13 state: present
You can see that the name of the packages to be installed is referencing the variables using the variable name, packages.
At the end of creating the playbook, the playbook will be in the form below.
2. Do a playbook syntax check.
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml --syntax-check
playbook: my-third-playbook.yml
3. Do a dry run if you wish.
(This step is not necessary, it just further explains how dry run works just as I have explained in one of the previous chapters)
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml -C
PLAY [Packages installation and deployment] *********************************************
.........
4. run the playbook.
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] *********************************************
.........
Like I said above, variables can be declared in many ways. Keep this on your right palm
Moving this exercise forward, let’s update the playbook to start and enable httpd, firewalld and autofs packages.
Steps
1. In the variable section, add the variable names which in this case are httpd_service, firewall_services, and autofs_services, and the variable values.
......
9 httpd_service: httpd
10 firewall_services: firewalld
11 autofs_services: autofs
2. In the task section, add the tasks referencing the variables.
..............
18 - name: start and enable httpd service
19 service:
20 name: "{{ httpd_service }}"
21 enabled: true
22 state: started
23
24 - name: start and enable firewall services
25 service:
26 name: "{{ firewall_services }}"
27 enabled: true
28 state: started
29
30 - name: start and enable autofs
31 service:
32 name: "{{ autofs_services }}"
33 enabled: true
34 state: started
3. Do a playbook syntax check
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml --syntax-check
playbook: my-third-playbook.yml
4. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] ***********************************************************************************
.....
ok: [localhost]
......
Moving this example forward, let’s add the https service to the firewall rule and add a test web server content to test if httpd has been well configured
Steps
1. In the variable section, add the variable name, which is firewall_rule, and the variable, which is https.
.......
9 httpd_service: httpd
10 firewall_services: firewalld
11 autofs_services: autofs
12 firewall_rule: https
2. Using the copy module, add a web server content in the task section for testing
..............
44 - name: copy a basic website content to test
45 copy:
46 content: "Hello World"
47 dest: /var/www/html/index.html
3. Do a playbook syntax check
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml --syntax-check
playbook: my-third-playbook.yml
4. Run the playbook.
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] ************************************************************
.......
Moving this example forward, let’s make sure the packages are updated to the latest
Steps
1. In the task section, add the task to make sure the three packages installed have the latest update.
.........
49 - name: update packages variable to the latest
50 yum:
51 name: "{{ packages }}"
52 state: latest
2. Do a playbook syntax check
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml --syntax-check
playbook: my-third-playbook.yml
3. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment]
.......
Moving this example forward, do a test from the local server using the uri module to see if the httpd package was successfully deployed on hqdev1.tekneed.com
Steps
1. Add a new play since we are going to be testing from the local server and also add the task to verify that the web content is accessible
55 - name: Test if httpd was successfully deployed
56 hosts: localhost
57 tasks:
58 - name: verify if the web content is accessible
59 uri:
60 url: htpp://hqdev1.tekneed.com
61 return_content: yes
62 status_code: 200
2. do a syntax check
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml --syntax-check
playbook: my-third-playbook.yml
3. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment]
.......
TASK [verify if the web content is accessible] *************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error unknown url type: htpp>", "redirected": false, "status": -1, "url": "htpp://hqdev1.tekneed.com"}
You can see that we have hit a road block. If you look at the error, it points to the last task. It showed
"url": "htpp://hqdev1.tekneed.com"}
This is because there was a typo. It should be http and not htpp, hence, we need to correct this in the playbook to fix this error. Though the typo was corrected in step 1 screenshot.
4. Rerun the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment]
.......
Now, you can see that the playbook ran successfully.
5. verify.
[lisa@drdev1 ~]$ curl http://hqdev1.tekneed.com
Hello World[lisa@drdev1 ~]$
So far so good, the playbook data for this example is as below
---
- name: Packages installation and deployment
hosts: group1
vars:
packages:
- httpd
- firewalld
- autofs
httpd_service: httpd
firewall_services: firewalld
autofs_services: autofs
firewall_rule: http
tasks:
- name: Install packages
yum:
name: "{{ packages }}"
state: present
- name: start and enable httpd service
service:
name: "{{ httpd_service }}"
enabled: true
state: started
- name: start and enable firewall services
service:
name: "{{ firewall_services }}"
enabled: true
state: started
- name: start and enable autofs
service:
name: "{{ autofs_services }}"
enabled: true
state: started
- name: allow apache in firewall
firewalld:
service: "{{ firewall_rule }}"
state: enabled
permanent: true
immediate: true
- name: copy a basic website content to test
copy:
content: "Hello World"
dest: /var/www/html/index.html
- name: update packages variable to the latest
yum:
name: "{{ packages }}"
state: latest
- name: Test if httpd was successfully deployed
hosts: localhost
tasks:
- name: verify if the web content is accessible
uri:
url: http://hqdev1.tekneed.com
return_content: yes
status_code: 200
Defining Ansible Variables Outside Of Ansible Playbook
Variables can be defined outside of a playbook file.
Just as I mentioned in this and the previous lesson, one should always endeavor to create a playbook that is easy to understand and troubleshoot, and putting variables in a playbook can make the playbook long, especially when one will have to define so many variables in the playbook.
Apart from defining variables in a playbook, variables can also be defined in an inventory, in an external file, and a command line using Ansible ad hoc
Using the example above, we are going to define the variables we defined in the playbook outside of the playbook in an external file.
Variables can be defined in 22 different ways and these ways take order of precedence, hence, you need to be mindful of how you define variables. You can click here to see the order of precedence.
To define the variables we defined in our last example in a file, follow the steps below:
1. Edit the playbook and change the hosts value in the first play to “all”. Also, delete all the variables in the playbook.
NOTE: changing the hosts value to all means that the tasks in the play will execute on all managed hosts in the inventory file.
[lisa@drdev1 ~]$ vim my-third-playbook.yml
1 ---
2 - name: Packages installation and deployment
3 hosts: all
4 tasks:
5 - name: Install packages
6 yum:
7 name: "{{ packages }}"
8 state: present
.............
The playbook after editing will be as below.
2. create the variable file and define the variables in the file.
*create the variable file for all the inventory group variables. (inventory group_vars/all).
In the order of variable precedence, this falls in number 4.
[lisa@drdev1 ~]$ mkdir group_vars
[lisa@drdev1 ~]$ vim group_vars/all
packages:
- httpd
- firewalld
- autofs
httpd_service: httpd
firewall_services: firewalld
autofs_services: autofs
firewall_rule: http
3. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] *******************************************************
Moving this example forward, let’s create a variable for individual groups (inventory group_vars/*), in this case, group1 only.
In the order of precedence, this falls in number 6.
Steps
1. create the variable file and define the variables in the file.
This time around, let’s add one more package called kmod-kvdo to the packages variable.
[lisa@drdev1 ~]$ vim group_vars/group1
packages:
- httpd
- firewalld
- autofs
- kmod-kvdo
httpd_service: httpd
firewall_services: firewalld
autofs_services: autofs
firewall_rule: http
This means that the variables will be executed only on group1 managed hosts in the inventory file.
2. Run the playbook.
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] *******************************************************
Moving this example forward, let’s create a variable for individual hosts (inventory host_vars/* ), in this case, hqdev1.tekneed.com only
In the order of precedence, this falls in number 9.
Steps
1. create the variable file and define the variables in the file.
[lisa@drdev1 ~]$ mkdir host_vars
[lisa@drdev1 ~]$ vim host_vars/hqdev1.tekneed.com
Let’s also add one more package, gdisk to the packages variable.
packages:
- httpd
- firewalld
- autofs
- kmod-kvdo
- gdisk
httpd_service: httpd
firewall_services: firewalld
autofs_services: autofs
firewall_rule: http
2. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook my-third-playbook.yml
PLAY [Packages installation and deployment] *******************************************************
This means the variables will be executed on hqdev1.tekneed.com only.
In the examples we have done so far, we have been able to declare variables in four different ways which are play vars (12), inventory group_vars/all (4), inventory group_vars/* (6), and inventory host_vars/* (9).
Looking at the order of precedence, play var, which is number 12 takes higher precedence than all of them, followed by number 9, then number 6, and number 4.
Other Methods of Defining Variables In Ansible
Having defined variables in the previous example in four different ways, let’s again define a variable using number 14 (play vars_file) in the order of precedence using the example below.
EXAMPLE I
Steps
1. create a playbook that defines the variables inside of the playbook with the syntax, vars_file, and pair, which is classified.yml
---
- name: create users
hosts: hqdev1.tekneed.com
vars_files:
- classified.yml
tasks:
- name: create users and password
user:
name: "{{ username }}"
password: "{{ password }}"
state: present
2. create the variable file
[lisa@drdev1 ~]$ vim classified.yml
username: tayo
password: toyota
3. Do a syntax check on the playbook
[lisa@drdev1 ~]$ ansible-playbook play3.yml --syntax-check
playbook: play3.yml
[lisa@drdev1 ~]$
4. Run the playbook.
[lisa@drdev1 ~]$ ansible-playbook play3.yml
PLAY [create users] ************************************************************
ERROR! Attempting to decrypt but no vault secrets found
[lisa@drdev1 ~]$
NB: Don’t worry about the error, we will look at how to fix such errors as we go on in this course
EXAMPLE II
Let’s create another playbook and define its variable outside of the playbook.
Steps
1. create a playbook
[lisa@drdev1 ~]$ vim play4.yml
---
- name: create users
hosts: hqdev1.tekneed.com
tasks:
- name: create users and password
user:
name: "{{ username }}"
password: "{{ password }}"
state: present
2. create the variable file
[lisa@drdev1 ~]$ mkdir -p host_vars/hqdev1.tekneed.com/
[lisa@drdev1 ~]$ vim host_vars/hqdev1.tekneed.com/classified.yml
username: tayo
password: toyota
3. Do a syntax check on the playbook
[lisa@drdev1 ~]$ ansible-playbook play4.yml --syntax-check
playbook: play4.yml
4. Run the playbook
[lisa@drdev1 ~]$ ansible-playbook play4.yml
PLAY [create users] ************************************************************
ERROR! Attempting to decrypt but no vault secrets found
Ignore the error for now, we will treat how to fix it in the next lesson.
As we go on in this course, we will look at the other ways variables can be declared with other examples.
You can also click on this link to see more ways ansible variables can be defined.
Class Activity
Create a playbook with variables that must install, start and enable the autofs service
If you like this article, you can support us by
1. sharing this article.
2. Buying the article writer a coffee (click here to buy a coffee)
3. Donating to move our project to the next level. (click here to donate)
If you need personal training, send an email to info@tekneed.com
Click Here To Watch Video On Creating and Managing Ansible Variables In Linux
RHCE EX294 Exam Practice Question On Creating & Managing Ansible Variables
Your feedback is welcomed. If you love others, you will share with others
Leave a Reply