Ansible Variables
Ansible Variables allow you to customize your playbooks and roles by using dynamic values instead of hardcoding everything. Variables enable you to create more flexible and reusable playbooks by defining specific values that can be changed based on the environment or host.
1. What are Ansible Variables?
Ansible variables are key-value pairs that allow you to pass dynamic data into your playbooks and roles. Instead of hardcoding values, variables make it easier to customize tasks based on the environment, host, or role.
Example:
---
vars:
package_name: nginx
service_name: nginx
tasks:
- name: Install web server
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
- name: Start web server
ansible.builtin.service:
name: "{{ service_name }}"
state: started
In this example, package_name and service_name are variables, allowing you to change the package and service name without altering the task logic.
2. Defining Variables
You can define variables in several places, each with different levels of precedence. The most common methods are:
- In the playbook: Variables can be defined directly within a playbook under the
varssection.
vars:
package_name: nginx
- In the inventory: Variables can be defined per host or group in the inventory file.
[webservers]
web1.example.com ansible_user=ubuntu service_name=nginx
- In a separate variables file: Variables can be defined in external files and included in playbooks for better organization.
# vars.yml
package_name: nginx
service_name: nginx
Include this in your playbook:
---
- name: Playbook with external variables
hosts: webservers
vars_files:
- vars.yml
3. Using Variables
Variables are referenced using Jinja2 syntax ({{ variable_name }}) inside tasks, templates, and other parts of the playbook.
Example:
- name: Install web server
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
In this case, package_name will dynamically replace {{ package_name }} with the actual value when the playbook runs.
4. Types of Variables
Ansible allows you to define variables in different ways, based on their scope and use cases:
- Host Variables: Set variables specific to each host in the inventory file.
web1.example.com ansible_user=ubuntu
- Group Variables: Apply variables to an entire group of hosts in the inventory.
[webservers:vars]
ansible_user=ubuntu
- Playbook Variables: Defined within a playbook’s
varssection or in an external variables file.
vars:
package_name: nginx
-
Role Variables: Variables specific to roles are defined in the role’s
defaults/main.ymlorvars/main.yml. -
Fact Variables: Gathered by Ansible about the target system using the
gather_factsfeature.
5. Precedence and Variable Overriding
Ansible allows you to define variables in many places, but they follow a strict order of precedence, with the highest priority being:
- Extra vars: Variables passed at the command line using
--extra-vars(ansible-playbook playbook.yml --extra-vars "package_name=nginx"). - Playbook-specific vars: Variables defined in the playbook under
vars. - Host and group vars: Variables defined per host or group in the inventory.
- Role defaults: Variables set in a role's
defaults/main.yml.
Higher precedence variables override lower precedence ones. This flexibility allows you to adapt to different environments easily.
6. Variable Scopes
Variables can be scoped globally, per group, per host, or even within a role. Ansible determines which variables to apply based on the scope and precedence.
Global Scope: Variables that apply to all tasks and hosts. Group Scope: Variables that apply to a group of hosts. Host Scope: Variables that apply to a specific host. Role Scope: Variables that are only available within a role.
7. Using Variables in Roles
Roles often rely on variables to be more flexible and customizable. Variables can be defined in the role’s defaults, vars, or passed in from playbooks or inventory.
Example (Role variable in defaults/main.yml):
nginx_package: nginx
nginx_service: nginx
In the playbook, you can override these variables when calling the role:
---
- name: Setup web servers
hosts: webservers
roles:
- role: nginx
vars:
nginx_service: custom-nginx
This will use the custom value custom-nginx for the nginx_service variable, overriding the default.
8. Registering Variables
You can capture the output of a task and store it in a variable using the register keyword. This allows you to use the result of one task in later tasks.
Example:
- name: Check if Nginx is installed
ansible.builtin.shell: dpkg -l | grep nginx
register: nginx_installed
- name: Install Nginx if not installed
ansible.builtin.apt:
name: nginx
state: present
when: nginx_installed.rc != 0
In this example, the output of the shell task is stored in nginx_installed, and the when condition checks the rc (return code) to decide whether to run the installation task.
9. Using Facts as Variables
Ansible automatically gathers facts about the target system (like IP address, OS type, CPU architecture) and makes them available as variables. These are useful for customizing tasks based on system properties.
Example:
- name: Display the operating system
debug:
msg: "The system is running {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
Ansible facts provide a wealth of information, which you can use to adapt your playbooks dynamically.
10. Example Playbook with Variables
Here is a complete example of a playbook using variables:
---
- name: Setup web servers
hosts: webservers
vars:
package_name: nginx
service_name: nginx
tasks:
- name: Install web server
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
- name: Start web server
ansible.builtin.service:
name: "{{ service_name }}"
state: started
In this example, the playbook installs and starts the web server using variables, making it easy to change the package_name and service_name values in one place.
Conclusion
Ansible Variables are an essential tool for creating flexible and reusable playbooks and roles. By defining variables at different scopes, using facts, and leveraging variable precedence, you can efficiently manage complex tasks across different environments. Whether you are working on a small automation task or a large infrastructure setup, mastering variables will significantly improve the flexibility of your Ansible projects.