In Ansible, variables are the key to flexible and reusable automation codes that are easily maintainable. They let you define reusable variables throughout the playbooks, roles, and templates – making configurations dynamic and adaptable.
Basically, Ansible variables are user-defined or system-generated values that are referenced across multiple tasks, templates, and roles. Kind of like placeholders or labels that represent data like usernames, file paths, package names, or the entire configuration. So, instead of hardcoding values like this:
name: Install nginx
apt:
name: nginx
state: present
Get exclusive access to all things tech-savvy, and be the first to receive
the latest updates directly in your inbox.
You can use a variable:
name: Install web server
apt:
name: “{{ web_package }}”
state: present
This makes it easy to change the value of the variable in one place, which means it is perfect for managing different environments like dev, staging, and production.
Basic Variable Syntax in Ansible
To understand different types of Ansible variables, it is also important to first familiarize yourself with the basic syntax.
Defining Variables
Variables in Ansible are defined using key: value pairs. You can define them in:
- Playbooks
- Inventory files
- Host/group variable files
- vars or vars_files sections
- At runtime with –extra-vars
For example:

– name: Basic variable example
hosts: webservers
vars:
web_package: nginx
port_number: 80
tasks:
– name: Install web server
apt:
name: “{{ web_package }}”
state: present
Accessing Variables
To use a variable in a task or template, wrap the variable name in double curly braces: {{ variable_name }}
For example:
name: “{{ user_name }} created successfully”
Ansible uses Jinja2 templating, so you can also apply filters:
name: “{{ user_name | upper }}”
Variable Naming Rules
- Use letters, numbers, and underscores (_)
- Must start with a letter
- Case-sensitive
- Avoid dashes (-) and spaces
Example username: db_user: xyz
Setting Variables at the Command Line
You can pass variables dynamically using the –extra-vars (-e) flag:
ansible-playbook site.yml -e “web_package=nginx port_number=80”
Types of Ansible Variables
There are several different types of variables, designed for specific use cases and scopes. This is why it is important to understand how to define variables to write a cleaner and more flexible playbook.
- Playbook Variables
These Ansible variables are defined directly inside the playbook using the vars keyword.
Example:
– name: Use playbook vars
hosts: all
vars:
app_port: 8080
service_name: apache2
tasks:
– name: Start the service
service:
name: “{{ service_name }}”
state: started
- Inventory Variables
Defined in your inventory files or a separate group/ host variable files.
Example: inventory.ini
[web]
server1 ansible_host=192.168.1.10 app_port=8080
Example: group_vars/web.yml
app_port: 8080
These are automatically loaded when you target the related group or host.
- Host and Group Vars
Located in dedicated directories:
- host_vars/hostname.yml
- group_vars/groupname.yml
They allow precise customization per host or group.
Example: host_vars/server1.yml
timezone: UTC
Example: group_vars/dbservers.yml
db_port: 5432
- Facts (System Variables)
Facts are Ansible system variables that are set up automatically by the setup module. They contain remote system details, such as IP, OS version, memory, and more.
Example:
ansible_facts[‘ansible_distribution’]
ansible_facts[‘ansible_hostname’]
Or simply:
ansible_hostname
ansible_distribution
You can also define your own facts using set_fact.
- Extra Vars (–extra-vars)
Ansible variables that are passed at runtime using the CLI -e or – -extra-vars. They are on the top in the precedence order and can override most other variable types.
Example:
ansible-playbook site.yml -e “app_port=9090 service_name=nginx”
You can also pass JSON:
ansible-playbook site.yml -e ‘{“app_port”: 9090, “debug_mode”: true}’
Variable Precedence in Ansible
When the same Ansible variable is defined in multiple places, variable precedence comes in. Ansible follows a system for a well-defined order to determine which variable value should be used.
Simplified Variable Precedence (Highest to Lowest):
- Extra vars (-e)
- Task-level variables (e.g., set_fact, or in vars within tasks)
- Block-level vars
- Play-level vars and vars_files
- Role defaults (defaults/main.yml)
- Inventory variables (host/group vars)
- Facts (via setup)
- Playbook-defined variables
- Command-line inventory variables
- Environment variables
For example:
If you define app_port in your playbook, but also pass it via –extra-vars, the CLI value will override it.
ansible-playbook site.yml -e “app_port=9000”
Using Variables in Playbooks
Variables can be used in almost all parts of a playbook, including tasks, handlers, loops, conditions, templates, and more.
Using Variables in Tasks
tasks:
– name: Install a package
apt:
name: “{{ package_name }}”
state: present
Using Variables in Loops
vars:
users:
– alice
– bob
tasks:
– name: Create users
user:
name: “{{ item }}”
loop: “{{ users }}”
Using Variables in Conditions
tasks:
– name: Restart web server if enabled
service:
name: apache2
state: restarted
when: webserver_enabled
Using Variables in Templates
Inside a Jinja2 template (.j2), you can insert variables like this:
server_name = {{ hostname }}
listen_port = {{ app_port }}
Defining Variables in Different Locations
Ansible offers flexible ways to define variables depending on your use case. Here are the most common:
- vars in Playbook
vars:
timezone: UTC
- vars_files (External Variable Files)
Useful for separating data from logic.
vars_files:
– vars/common.yml
common.yml
db_host: localhost
db_port: 5432
- vars_prompt (Prompt at Runtime)
Ask the user to input a variable value when running the playbook.
vars_prompt:
– name: admin_password
prompt: “Enter the admin password”
private: yes
- set_fact (Dynamic Variables)
Set a variable during execution.
tasks:
– name: Set a dynamic variable
set_fact:
backup_dir: “/var/backups/{{ inventory_hostname }}”
Real-World Examples of Using Ansible Variables
Ansible variables are one of the most powerful variables when used in real world scenarios. Here are some practical examples that show how you can make your playbooks dynamic and reusable.
- Dynamic User Creation
When you need to create multiple users with a specific attribute, you can define a list of users as variables and loop through them:
Example:
vars:
users:
– name: alice
uid: 1101
shell: /bin/bash
– name: bob
uid: 1102
shell: /bin/zsh
tasks:
– name: Create system users
user:
name: “{{ item.name }}”
uid: “{{ item.uid }}”
shell: “{{ item.shell }}”
state: present
loop: “{{ users }}”
- Package Installation
Use variables to define which package to install, making it easy to switch between distros.
Example:
vars:
web_packages:
– nginx
– php-fpm
tasks:
– name: Install web server packages
apt:
name: “{{ item }}”
state: present
loop: “{{ web_packages }}”
Or a single variable:
vars:
database_package: postgresql
tasks:
– name: Install database
apt:
name: “{{ database_package }}”
state: present
- Service Configuration
Ansible variables that can drive the configuration of services like Nginx or Apache, especially when you are using templates.
Example: vars in playbook
vars:
server_name: example.com
listen_port: 8080
tasks:
– name: Deploy Nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
Example: nginx.conf.j2 template
server {
listen {{ listen_port }};
server_name {{ server_name }};
location / {
proxy_pass http://localhost:3000;
}
}
Best Practices for Managing Variables
Follow these best practices to manage Ansible variables efficiently:
- Use Clear and Consistent Naming Conventions
Use lowercase letters and underscores: db_host, user_list. Avoid reserved or generic names like data, info, or vars.
- Group Variables Logically
Use group_vars/ and host_vars/ directories to separate configuration by host or group.
Example structure:
group_vars/
webservers.yml
dbservers.yml
host_vars/
server1.yml
- Externalize Variables with vars_files
Keep variables separate from your playbook logic to make playbooks cleaner and easier to reuse.
vars_files:
– vars/common.yml
– vars/environment/dev.yml
- Avoid Hardcoding Values
Use variables wherever possible.
dest: “/home/{{ username }}/.ssh/authorized_keys”
- Leverage set_fact for Dynamic Values
Use set_fact to define variables at runtime, especially when their value depends on a condition or loop.
– set_fact:
backup_path: “/backup/{{ inventory_hostname }}”
- Sanitize and Validate Variables
Use the default filter and when conditions to handle missing or incorrect variables gracefully.
server_port: “{{ server_port | default(8080) }}”
- Keep Sensitive Data Secure
Use the Ansible vault for sensitive data.
ansible-vault encrypt secrets.yml
- Test and Debug Variables
Use debug tasks to print variable values for troubleshooting.
– debug:
var: my_variable
Common Mistakes and Troubleshooting Tips For Ansible Variables
Mistake | Description | How to Fix / Avoid It |
Incorrect variable syntax | Forgetting the double curly braces or using wrong characters. | Use {{ variable_name }} with proper spacing. Don’t use $, %, or single {}. |
Using dashes in variable names | YAML allows it, but Ansible treats it as invalid in some contexts. | Use underscores (_) instead: my_variable instead of my-variable. |
Undefined variables causing playbook failure | Playbooks fail if you reference a variable that doesn’t exist. | Use the default filter: `{{ some_var |
Wrong variable precedence assumption | A lower-priority variable overrides a higher-priority one unexpectedly. | Understand Ansible’s variable precedence and use –extra-vars for overrides. |
Mixing up variable scope | Trying to use a host variable in a group context or vice versa. | Be clear about where and for whom the variable is defined (e.g., group_vars, host_vars). |
Forgetting to quote strings with special characters | Characters like : or * can break YAML parsing. | Wrap such values in quotes: “pass:word” |
Not using set_fact for dynamically generated vars | You try to use a new variable without properly setting it first. | Use set_fact to define variables during playbook execution. |
Overriding global vars unintentionally | Reusing variable names in different scopes without realizing. | Use specific, descriptive names to avoid clashes, especially in roles. |
Conclusion – Ansible Variables
Ansible variables are the real backbone of dynamic and functional automation. Whether you are configuring multiple environments, managing different hosts, or simplifying complex logic, mastering variables is the way for cleaner playbooks.
Frequently Asked Questions
How do I define variables in an Ansible playbook?
You can define them under the vars:
section in a playbook or import them from a separate file using vars_files
.
Can I use facts as variables in Ansible?
Yes, Ansible automatically gathers facts about hosts (like OS, IP address, etc.), which can be used as read-only variables in tasks and templates.
How do I troubleshoot variable-related issues?
Use the debug
module to print variable values and check for scope conflicts, typos, or incorrect precedence.