Variables in Ansible
Variables are used to store values that can be later used in the playbook.
Host variable
- We will use our default inventory file - /etc/ansible/hosts
In this inventory file, we will define 2 variables for server 2
Demo Inventory file - server1
server2 http_port=8080 pkg=httpd server3
These 2 variables http_port and pkg are only applicable for server2. Now we will use these variables with the ansible playbook.
For accessing variables in a playbook we define variable names inside double curly braces {{variable name}}
---
- hosts: group1
user: ansible
become: yes
connection: ssh
gather_facts: no
tasks:
- name: Testing first variaable http_port
debug: # debug is a module name
msg: "The HTTP port is {{http_port}}"
- name: Testing second variable package name
debug:
msg: " The package name is {{pkg}}"
Group variables
- Group variables can be assigned to a group and all the hosts part of that group have access to these variables.
# Inventory file
[app] # app is a group consisting 2 servers
server1
server3
[db] # db is also another group of 2 servers
server2
server4
[db:var] # defining variables for db group servers
http_port=8080 #these 2 variables are accessible to all server in db group
pkg=httpd
# Inventory group variables yaml file
---
- hosts: db # we are trying to access variables in the db group
user: ansible
become: yes
connection: ssh
gather_facts: no
tasks:
- name: Testing first variable http_port
debug:
msg: "The HTTP port is {{http_port}}"
- name: Testing second variable package name
debug:
msg: " The package name is {{pkg}}"
Defining a variable in Playbook
# Defining variables in a playbook
- hosts: server2
user: ansible
become: yes
connection: ssh
vars: # Defining a playbook under vars section
pkgname: httpd
tasks:
- name: Install package
yum:
name: '{{pkgname}}' # Accessing the variable pkgname
state: installed
- We can pass any package name as a value to variable pkgname and that package will be installed in server2
Defining variables using the command line
Variables can also be passed on the command line like below using --extra-vars argument or -e in key=value format and variable separated by space
ansible-playbook text.yml --extra-vars "one_var = test1 other_var = test2"
All the values will be treated as strings. If we have some value in integer or boolean then a better way is to define these in JSON format
ansible-playbook test.yml --extra-vars '{"one_var":"test1", "other_var":"test2"}'
If we have a JSON or YAML file then we can also import it into our playbook like below
ansible-playbook test.yml --extra-vars "@file1.json"
# Accessing variables using the command line - hosts: server2 user: ansible become: yes connection: ssh vars: username: CJ # Defining variables tasks: - name: Show user details debug: msg: "USERNAME = {{username}}" # Printing username
We define a variable username with a value of CJ. In this, we will define the same variable using the username and assign a different value using the command line
ansible-playbook command_line_vars.yml -e "username = admin"
Types of Variables in Ansible
- User-Defined Variables
The variable defined in the playbook simply in key-value pair
2. System facts
These are the default variables in which the Ansible Control Server stores information after discovering from nodes. Ansible_facts contain all information in JSON format.
{{ansible_facts['devices']['xvda']['mode1']}}
{{ansible_facts['nodename']}}
3. Registered Variables
These are the variables in which the output of your task will be stored on the Ansible Control Server. When we want to run a command on a remote computer and then store the output in a variable and use a piece of information from the output later in playbooks.
E.g. - When we run a command service httpd status and register its output in a variable apache_status
# Register variable in playbook
- hosts: server2
user: ansible
become: yes
connection: ssh
gather_facts: no
tasks:
- name: Get web server status
command: service httpd status
register: apache_status
- name: web server status only
debug:
var: apache_status
Here apache_status is variable so the output of the command "service httpd status" will be stored in the variable apache_status. So by using the register variable, you can store the output of the task. To print that output we use debug module. It will return output in JSON format
Whenever you executed any task or command ansible will give you some return values like. - changed, cmd, delta, end, failed, rc, start, stderr, stderr_lines, stdout, stdout_lines
These return values depend on the task you executed. In the above return values our output will be stored in stdout, So to print exact output without any extra return values we can use like variablename.stdout or you can use stdout_lines. Stdout_lines will split the output into line by line.
# Printing web server status using register variable
- hosts: server2
user: ansible
become: yes
connection: ssh
gather_facts: no
tasks:
- name: Get web server status
command: service httpd status
register: apache_status
- name: web server status only
debug:
var: apache_status.stdout_lines
- Special Variable
Variables which is default to the system and can not be set by the user directly. But these will contain the data related to the system's internal state like version, and forks.
E.g.- inverntory_file, ansible_connection
Prompt for user input with vars_prompt
When running a playbook, there may be information that you need to collect at runtime. We can collect the information from the end user by specifying a
vars_prompt section in the playbook.
# Taking variable value during run time
---
- hosts: localhost
user: ansible
become: yes
connection: ssh
gather_facts: no
vars_prompt:
- name: user_name
prompt: Enter user name
private: no
- name: password
prompt: Enter password
private: yes
tasks:
- name: Printing username and password
debug:
msg: "Username is {{user_name}} and password is {{password}}"
private: no - means the user can see the entered text in the terminal
private: yes - means the user will not see anything in the terminal while entering the password
Read and access variables from separate YAML or JSON file
We will create a separate YAML or JSON file which will only contain a bunch of variables and using a playbook we will refer to this YAML or JSON file to read and access the variable value.
Reading from YAML file
# variables.yaml file
USERNAME: CJ
COURSE: Ansible
TOPIC: Variables
# Accessing variables from variables.yaml file
---
- name: Collect variables from YAML file
hosts: localhost
gather_facts: no
var_files: variables.yaml # Accessing variables.yaml file
tasks:
- name: varaibles from yaml file
debug:
msg: # Printing variables defined in variables.yaml file
- "Username is {{USERNAME}}"
- "This is {{COURSE}}"
- "Leaning {{TOPIC}}"
- Reading from JSON file
# variables.json file
{
"a": 50,
"b": [1,2,3,4],
"c": {"one":1, "two":2}
}
# Accessing variables from variables.json file
---
- name: Collect variables from JSON file
hosts: localhost
gather_facts: no
var_files:
- ~/custom_vars.json
tasks:
- name: varaibles from json file
debug:
msg:
- "Value of b is {{b}}"
- "Second index value of b is {{b[1]}}"
I hope you enjoyed this article, if you have any questions, comments, or feedback or if I made a mistake feel free to comment down below.