Variables and Facts
Variable Types
Basic Variables
# Simple variables
string_var: "Hello World"
number_var: 42
boolean_var: true
list_var:
- item1
- item2
- item3
dict_var:
key1: value1
key2: value2
nested:
key3: value3
Special Variables
# Ansible predefined variables
ansible_host: "192.168.1.10"
ansible_port: 22
ansible_user: "deploy"
ansible_connection: "ssh"
# Magic variables
inventory_hostname: "web1.example.com"
group_names: ["webservers", "production"]
hostvars: {}
groups: {}
Variable Scope
Host Variables
# host_vars/web1.example.com.yml
apache_port: 80
doc_root: "/var/www/html"
Group Variables
# group_vars/webservers.yml
http_port: 80
max_clients: 200
Play Variables
- name: Configure web servers
hosts: webservers
vars:
http_port: 80
max_clients: 200
vars_files:
- vars/common.yml
- vars/secure.yml
Role Variables
# roles/webserver/defaults/main.yml
http_port: 80
doc_root: "/var/www/html"
# roles/webserver/vars/main.yml
nginx_version: "stable"
Variable Precedence
- Command line (
-e
or --extra-vars
)
- Task variables
- Block variables
- Role and include variables
- Play variables
- Host facts
- Host vars
- Group vars
- Role defaults
- Inventory variables
Facts
System Facts
- name: Display system facts
debug:
msg: |
OS Family: {{ ansible_os_family }}
Distribution: {{ ansible_distribution }}
Distribution Version: {{ ansible_distribution_version }}
Architecture: {{ ansible_architecture }}
Processor Cores: {{ ansible_processor_cores }}
Total Memory: {{ ansible_memtotal_mb }}
Custom Facts
# /etc/ansible/facts.d/custom.fact
[application]
version=1.0.0
environment=production
deployed_date=2024-03-15
Using Facts
- name: Use custom facts
debug:
msg: "App version: {{ ansible_local.custom.application.version }}"
Variable Manipulation
Filters
# String manipulation
uppercase: "{{ variable | upper }}"
lowercase: "{{ variable | lower }}"
json_string: "{{ variable | to_json }}"
yaml_string: "{{ variable | to_yaml }}"
# List manipulation
first_item: "{{ list_var | first }}"
last_item: "{{ list_var | last }}"
sorted_list: "{{ list_var | sort }}"
unique_items: "{{ list_var | unique }}"
# Dictionary manipulation
dict_keys: "{{ dict_var | dict2items }}"
combined_dict: "{{ dict1 | combine(dict2) }}"
Jinja2 Operations
# Conditionals
result: "{{ 'high' if value > 90 else 'low' }}"
# Loops
devices: "{{ ['sda', 'sdb', 'sdc'] | map('regex_replace', '^', '/dev/') | list }}"
# Math operations
total: "{{ value1 + value2 }}"
percentage: "{{ (value / total * 100) | round(2) }}"
Variables in Templates
Template Usage
# templates/nginx.conf.j2
server {
listen {{ http_port }};
server_name {{ server_name }};
{% for domain in allowed_domains %}
server_name {{ domain }};
{% endfor %}
location / {
root {{ doc_root }};
{% if enable_php %}
index index.php index.html;
{% else %}
index index.html;
{% endif %}
}
}
Environment Variables
Setting Environment Variables
- name: Run with environment variables
shell: echo $DATABASE_URL
environment:
DATABASE_URL: "postgresql://user:pass@localhost/db"
API_KEY: "{{ lookup('env', 'API_KEY') }}"
Using Environment Files
- name: Load environment file
include_vars:
file: "{{ env }}.yml"
name: env_vars
Variable Registration
Registering Task Output
- name: Check service status
command: systemctl status nginx
register: service_status
ignore_errors: true
- name: Display service status
debug:
msg: "Nginx is {{ 'running' if service_status.rc == 0 else 'stopped' }}"
Lookups
File Lookups
password: "{{ lookup('file', '/path/to/password.txt') }}"
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
Other Lookups
# Environment variables
api_key: "{{ lookup('env', 'API_KEY') }}"
# DNS lookup
ip_address: "{{ lookup('dig', 'example.com') }}"
# Random values
random_password: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits') }}"
# AWS Secret
aws_secret: "{{ lookup('aws_secret', 'myapp/db_password') }}"
Variable Protection
Vault Protection
# vars/secure.yml
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566653063336164663966303231363934653561363964363833313662
6431626536303530376336343832656537303632313433360a626438346336353331386135323734
62656361653630373231613662633962316233633936396165386439616533353965373339616234
3430613539666330390a373661636536358
# Using vault variables
- name: Configure database
template:
src: db_config.j2
dest: /etc/app/database.conf
vars_files:
- vars/secure.yml
No Log Option
- name: Configure sensitive data
template:
src: secure_template.j2
dest: /etc/app/config
vars:
api_key: "secret123"
no_log: true
Variable Debugging
Debug Module
- name: Debug variables
debug:
var: variable_name
verbosity: 2
- name: Debug complex structure
debug:
msg: |
Host: {{ inventory_hostname }}
OS: {{ ansible_os_family }}
Memory: {{ ansible_memtotal_mb }}
Variable Inspection
- name: Dump all variables
debug:
msg: |
All variables:
{{ vars | to_nice_yaml }}
Best Practices
Variable Naming
# Good names
app_version: "1.0.0"
http_port: 80
max_connections: 1000
# Avoid
v: "1.0.0"
port: 80
max: 1000
Variable Organization
# Group related variables
database:
host: localhost
port: 5432
name: myapp
user: admin
max_connections: 100
application:
name: myapp
version: 1.0.0
environment: production
features:
logging: true
monitoring: true
Variable Documentation
# vars/main.yml
---
# Database configuration
# Required for application database connection
db_host: localhost # Database server hostname
db_port: 5432 # PostgreSQL default port
db_name: myapp # Application database name
# Application settings
app_name: myapp # Application identifier
app_port: 8080 # Application listening port
debug_mode: false # Enable debug logging