Ansible Variables

Variables are what transform static playbooks into dynamic, reusable automation. Without variables, you would write a separate playbook for each environment, each server, and each configuration variation. With variables, you write one playbook and adjust its behaviour through data. This lesson covers every practical variable mechanism you need for professional Ansible work.

Defining Variables Inline with vars

---
- name: Deploy application
  hosts: webservers
  vars:
    app_name: myapp
    app_port: 8080
    app_user: deploy
    app_directory: /opt/{{ app_name }}
  tasks:
    - name: Create app directory
      file:
        path: "{{ app_directory }}"
        state: directory
        owner: "{{ app_user }}"

The vars: block is the simplest way to define play-scoped variables. Note that variables can reference other variables: app_directory: /opt/{{ app_name }}. This is evaluated at runtime, so app_directory becomes /opt/myapp.

Variable Files with vars_files

As the number of variables grows, keeping them in the playbook becomes unwieldy. The vars_files directive loads variables from external YAML files:

---
- name: Deploy application
  hosts: webservers
  vars_files:
    - vars/common.yml
    - vars/{{ environment }}.yml
  tasks: ...

Contents of vars/common.yml:

app_name: myapp
app_user: deploy
log_level: INFO

Contents of vars/production.yml:

app_port: 443
db_host: prod-db.internal
ssl_enabled: true
log_level: WARNING

The dynamic file name vars/{{ environment }}.yml loads a different file based on the environment variable, which could be passed at runtime with -e environment=production. This pattern is one of the cleanest ways to manage environment-specific configuration.

Registering Task Output as Variables

The register keyword captures a task's return value and stores it as a variable for use in subsequent tasks:

- name: Check if application is running
  command: systemctl is-active myapp
  register: app_status
  ignore_errors: true

- name: Start application if it is not running
  service:
    name: myapp
    state: started
  when: app_status.rc != 0

The registered variable app_status is a dictionary containing the complete module return data. Common fields: .stdout, .stderr, .rc (return code), .changed, .failed. Use debug: var=app_status in a task to inspect the full structure of a registered variable.

Passing Variables at Runtime with -e

ansible-playbook deploy.yml -e "environment=production version=2.5.1"
ansible-playbook deploy.yml -e "@production-vars.yml"

The -e flag passes extra variables at the highest precedence level — they override everything else. The @ syntax loads extra variables from a file. Runtime variables are ideal for things that change per-deployment: version numbers, deployment targets, feature flags.

Magic Variables

Ansible provides built-in variables always available in playbooks:

  • inventory_hostname — Current host name from inventory
  • ansible_facts — Dictionary of all system facts
  • hostvars['hostname']['var_name'] — Access another host's variable
  • groups['groupname'] — List of hosts in a group
  • group_names — List of groups the current host belongs to

The debug Module for Variable Inspection

- name: Show variable values
  debug:
    var: app_directory

- name: Show a formatted message
  debug:
    msg: "Deploying {{ app_name }} version {{ version }} to {{ inventory_hostname }}"

The debug module is your primary tool for understanding what variable values look like at runtime. Insert debug tasks freely during development; remove or comment them out before committing to version control.

Try This: Environment-Aware Playbook

Create a playbook that loads a different vars_files file based on an env variable. Create two files: vars/dev.yml with http_port: 8080 and vars/prod.yml with http_port: 443. Run the playbook twice: once with -e env=dev and once with -e env=prod. Add a debug task that prints the port. Verify the correct port appears in each run.

Summary

Variables make playbooks dynamic and reusable. The vars block defines inline play-scoped variables. vars_files loads variables from external YAML files, supporting dynamic file selection for environment-specific configuration. The register keyword captures task output for conditional logic. Runtime variables passed with -e override all other sources. The debug module reveals variable values at runtime for troubleshooting.

Leave a Comment