Operations 18 min read

Mastering Ansible Playbook Variables: Priorities, Definitions, and Best Practices

This guide explains Ansible playbook variable handling, covering priority rules, YAML pitfalls, inventory definitions, host_vars/group_vars, var_files, vars_prompt, command‑line extra vars, role variables, facts, register, hostvars, and list/loop usage with practical code examples.

Raymond Ops
Raymond Ops
Raymond Ops
Mastering Ansible Playbook Variables: Priorities, Definitions, and Best Practices

Ansible Playbook Variables

1. Variable Priority

extra vars

(command line -e) – highest priority

Connection variables defined in inventory (e.g., ansible_ssh_user) – second priority

Other variables such as command‑line conversion, play variables, include variables, role variables – third priority

Variables defined directly in the inventory file – fourth priority

System‑discovered facts – fifth priority

Role default variables – lowest priority

Within the inventory list, a variable defined for a single host overrides a variable defined for a host group. The precedence order from high to low is: host_vars → inventory host variables → group_vars → inventory group variables.

1.1 YAML Pitfalls

When a value starts with {{ foo }} in YAML, the entire line must be quoted to avoid being interpreted as a dictionary.

|---
|---
|---
|hosts: app_servers
|vars:
|app_path: {{ base_path }}/data/web

Corrected version:

|---
|---
|---
|hosts: app_servers
|vars:
|app_path: "{{ base_path }}/data/web"

2. Ansible Playbook Variable Configuration Methods

2.1 Define Variables in the Inventory Host File

Variables can be placed directly in /etc/ansible/hosts and apply only to the specified host or group.

| $ egrep -v "^#|^$" /etc/ansible/hosts
| 10.4.7.101 key=20180101
| 10.4.7.102 key="niubility"
| $ cat ansi.yml
|---
|- hosts: all
|  gather_facts: False
|  tasks:
|   - name: haha
|     debug: msg="the {{ inventory_hostname }} value is {{ key }}"
| $ ansible-playbook ansi.yml
| PLAY [all]
| TASK [haha]
| ok: [10.4.7.101] => {"msg": "the 10.4.7.101 value is 20180101"}
| ok: [10.4.7.102] => {"msg": "the 10.4.7.102 value is niubility"}

2.2 Use host_vars and group_vars Directories

The default Ansible config directory ( /etc/ansible/ on Linux) can contain host_vars and group_vars sub‑directories for variable files.

Single‑host variables:

| $ cat /etc/ansible/host_vars/10.4.7.101
|---
|user: root
|pass: root@123

Group variables (e.g., for group test):

| $ cat /etc/ansible/group_vars/test
|---
|user: work
|pass: work@123

2.3 Define Variables via var_files

| $ cat vars.yml
|---
|key: jiayou
| $ cat bo.yml
|---
|- hosts: all
|  gather_facts: False
|  vars_files:
|   - vars.yml
|  tasks:
|   - name: display
|     debug: msg="the {{ inventory_hostname }} valus is {{ key }}"
| $ ansible-playbook bo.yml
| PLAY [all]
| TASK [display]
| ok: [10.4.7.101] => {"msg": "the 10.4.7.101 valus is jiayou"}
| ok: [10.4.7.102] => {"msg": "the 10.4.7.102 valus is jiayou"}

2.4 Use vars_prompt for Interactive Input

| $ cat prom.yml
|---
|- hosts: test
|  remote_user: root
|  vars_prompt:
|   - name: "var1"
|     prompt: "please input you name"
|     private: no
|   - name: "var2"
|     prompt: "please input you age"
|     private: yes
|     default: 18
|  tasks:
|   - name: display var1
|     debug: msg="your name of var1 is {{ var1 }}"
|   - name: display var2
|     debug: msg="you age of var2 is {{ var2 }}"
| $ ansible-playbook prom.yml
| please input you name: lvzhenjiang
| please input you age [18]: 23
| TASK [display var1]
| ok: [10.4.7.101] => {"msg": "your name of var1 is lvzhenjiang"}
| TASK [display var2]
| ok: [10.4.7.101] => {"msg": "you age of var2 is 23"}

2.5 Pass Variables on the Command Line ( --extra-vars )

| $ cat exap.yml
|---
|- hosts: '{{hosts}}'
|  remote_user: '{{user}}'
|  tasks:
|   - name: "一个测试"
|     debug: msg="your hosts is {{hosts}}, user is {{user}}"
| $ ansible-playbook exap.yml -e "hosts=test user=root"
| PLAY [test]
| TASK [一个测试]
| ok: [10.4.7.101] => {"msg": "your hosts is test, user is root"}

You can also supply variables from a file using -e "@filename".

| $ cat anhui.yml
|---
|hosts: test
|user: root
| $ ansible-playbook exap.yml -e "@anhui.yml"
| PLAY [test]
| TASK [一个测试]
| ok: [10.4.7.101] => {"msg": "your hosts is test, user is root"}

2.6 Define Variables Inside the Playbook

| $ cat playbook.yml
|---
|- hosts: test
|  remote_user: root
|  vars:
|   - dir1: /root/Ansible
|   - dir2: /root/Ansible/test1
|   - dir3: /root/Ansible/test2
|  tasks:
|   - name: Create New Folder
|     file: name={{ dir1 }} state=directory
|   - name: Create New Folder
|     file: name={{ dir2 }} state=directory
|   - name: Create New Folder
|     file: name={{ dir3 }} state=directory
| $ ansible-playbook playbook.yml
| PLAY [test]
| TASK [Create New Folder]
| changed: [10.4.7.101]

2.7 Define Variables via Roles

| # roles/vars/main.yml
| var1: value1
| var2: value2
| var3: value3
| # tasks/main.yml
| - name: create directory
|   file: name={{ dir }} state=directory
| - name: Get IP Address
|   shell: echo `{{ cmd }}` >> {{ dir }}/{{ file }}
| # vars/main.yml for role
| cmd: hostname -I
| # hosts file example
| [test]
| 10.4.7.101 dir=/root/node2
| 10.4.7.102 dir=/root/node1
| [test:vars]
| file=hostname.txt
| $ ansible-playbook -i hosts playbook.yml
| PLAY [test]
| TASK [test : create directory]
| ok: [10.4.7.101]
| TASK [test : Get IP Address]
| changed: [10.4.7.101]

2.8 Use Facts to Obtain Information

Facts are automatically discovered variables such as the remote host’s IP address or operating system.

| $ ansible test -m setup | grep "ansible_python_version"
| "ansible_python_version": "2.7.5",
| $ ansible test -m setup | grep "ansible_nodename"
| "ansible_nodename": "template",
| $ ansible test -m setup | grep "ansible_hostname"
| "ansible_hostname": "template"

Disable facts to speed up execution:

| $ cat anhui.yml
|---
|- hosts: test
|  gather_facts: no

2.9 Register Variables

The register keyword stores a task’s result in a variable for later use.

| $ cat register.yml
|---
|- hosts: test
|  remote_user: root
|  tasks:
|   - name: register bo_test
|     shell: hostname -I
|     register: info
|   - name: display info
|     debug: msg="this host ip is {{ info['stdout'] }}"
| $ ansible-playbook register.yml
| TASK [display info]
| ok: [10.4.7.101] => {"msg": "this host ip is 10.4.7.101 "}

2.10 hostvars Variable

hostvars

allows you to reference variables of other hosts.

| $ cat test.yml
|---
|- hosts: test
|  remote_user: root
|  gather_facts: False
|  tasks:
|   - name: this is test1
|     debug: msg="She is come from {{ hostvars['10.4.7.101']['addr'] }}"
|   - name: this is test2
|     debug: msg="I am {{ hostvars['10.4.7.102']['user'] }}, and age is {{ hostvars['10.4.7.102']['age'] }}"
| $ ansible-playbook test.yml
| TASK [this is test1]
| ok: [10.4.7.101] => {"msg": "She is come from beijing"}
| TASK [this is test2]
| ok: [10.4.7.101] => {"msg": "I am shibo, and age is 39"}

2.11 List, Loop, and Dictionary Variables

Variables can be lists, which can be iterated with loops.

| $ cat test.yml
|---
|- hosts: test
|  remote_user: root
|  gather_facts: False
|  vars:
|   - list: [1,2,3]
|  tasks:
|   - name: echo
|     debug: msg="{{ list }}"
| $ ansible-playbook test.yml
| TASK [echo]
| ok: [10.4.7.101] => {"msg": [1, 2, 3]}
| $ cat test.yml (loop example)
|---
|- hosts: 10.4.7.101
|  remote_user: root
|  gather_facts: False
|  vars:
|   - list: [1,2,3]
|  tasks:
|   - name: this is loop
|     debug: msg="{{ item }}"
|     with_items: "{{ list }}"
| $ ansible-playbook test.yml
| TASK [this is loop]
| ok: [10.4.7.101] => (item=1) => {"msg": 1}
| ok: [10.4.7.101] => (item=2) => {"msg": 2}
| ok: [10.4.7.101] => (item=3) => {"msg": 3}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

YAMLVariablesAnsiblePlaybook
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.