Ansible group_vars & host_vars: Organize Variables by Host and Group
By Luca Berton · Published 2024-01-01 · Category: linux-administration
Complete guide to Ansible group_vars and host_vars directories. Organize variables by group and host, use vault-encrypted files, understand variable.
group_vars and host_vars are directories where you store variables for groups and individual hosts. They keep your inventory clean and your variables organized by environment, role, or host.
Directory Structure
inventory/
├── production
├── staging
├── group_vars/
│ ├── all.yml # Variables for ALL hosts
│ ├── webservers.yml # Variables for webservers group
│ ├── dbservers.yml # Variables for dbservers group
│ └── webservers/ # Directory format (multiple files)
│ ├── vars.yml
│ └── vault.yml # Encrypted secrets
└── host_vars/
├── web01.example.com.yml
└── db01.example.com.yml
See also: AI-Assisted Inventory Generation in AAP 2.6 — Developer Preview
group_vars: Variables by Group
# group_vars/all.yml — applies to every host
ntp_server: ntp.example.com
dns_servers:
- 8.8.8.8
- 8.8.4.4
timezone: UTC
# group_vars/webservers.yml
http_port: 80
https_port: 443
max_connections: 1024
document_root: /var/www/html
# group_vars/dbservers.yml
postgresql_port: 5432
postgresql_max_connections: 200
postgresql_data_dir: /var/lib/postgresql/data
host_vars: Variables by Host
# host_vars/web01.example.com.yml
ansible_host: 10.0.1.50
server_id: 1
primary_site: true
# host_vars/web02.example.com.yml
ansible_host: 10.0.1.51
server_id: 2
primary_site: false
See also: ansible.cfg: Complete Configuration Guide for Ansible (2026)
Using Variables in Playbooks
- name: Configure web servers
hosts: webservers
tasks:
- name: Set up nginx
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
# Uses http_port, max_connections from group_vars/webservers.yml
# Uses ntp_server from group_vars/all.yml
# Uses server_id from host_vars/web01.yml
Directory Format (Multiple Files)
Split variables into multiple files per group:
group_vars/
└── webservers/
├── vars.yml # Non-sensitive variables
├── vault.yml # Encrypted secrets
└── ssl.yml # SSL-specific variables
# group_vars/webservers/vars.yml
http_port: 80
worker_processes: auto
# group_vars/webservers/vault.yml (encrypted)
vault_ssl_private_key: |
-----BEGIN PRIVATE KEY-----
...
vault_db_password: "s3cret"
# group_vars/webservers/ssl.yml
ssl_certificate: /etc/ssl/certs/site.pem
ssl_private_key: /etc/ssl/private/site.key
See also: Configure Ansible Dynamic Inventory for VMware in Simple Steps
Multi-Environment Setup
environments/
├── production/
│ ├── inventory
│ └── group_vars/
│ ├── all.yml
│ └── webservers.yml
├── staging/
│ ├── inventory
│ └── group_vars/
│ ├── all.yml
│ └── webservers.yml
└── development/
├── inventory
└── group_vars/
├── all.yml
└── webservers.yml
# environments/production/group_vars/all.yml
env: production
domain: example.com
replicas: 3
# environments/staging/group_vars/all.yml
env: staging
domain: staging.example.com
replicas: 1
# Run against specific environment
ansible-playbook site.yml -i environments/production/inventory
ansible-playbook site.yml -i environments/staging/inventory
Variable Precedence
From lowest to highest priority:
group_vars/all (lowest)
group_vars/
host_vars/
Play vars:
Task vars:
set_fact / register
-e / --extra-vars (highest)
# group_vars/all.yml
log_level: info
# group_vars/webservers.yml
log_level: warn # Overrides all.yml for webservers
# host_vars/web01.yml
log_level: debug # Overrides group_vars for web01 only
hostvars: Access Other Host's Variables
- name: Configure app to connect to DB
ansible.builtin.template:
src: database.yml.j2
dest: /etc/myapp/database.yml
vars:
db_host: "{{ hostvars['db01.example.com'].ansible_default_ipv4.address }}"
db_port: "{{ hostvars['db01.example.com'].postgresql_port }}"
Vault-Encrypted Variables
# Encrypt a file
ansible-vault encrypt group_vars/webservers/vault.yml
# Edit encrypted file
ansible-vault edit group_vars/webservers/vault.yml
# Run playbook with vault password
ansible-playbook site.yml --ask-vault-pass
Best practice — reference vault variables with a vault_ prefix:
# group_vars/webservers/vault.yml (encrypted)
vault_db_password: "actual_secret"
# group_vars/webservers/vars.yml (not encrypted)
db_password: "{{ vault_db_password }}"
Practical Examples
Complete Project Structure
myproject/
├── ansible.cfg
├── site.yml
├── roles/
│ ├── common/
│ ├── webserver/
│ └── database/
├── inventory/
│ ├── hosts
│ ├── group_vars/
│ │ ├── all/
│ │ │ ├── vars.yml
│ │ │ └── vault.yml
│ │ ├── webservers.yml
│ │ └── dbservers.yml
│ └── host_vars/
│ ├── web01.yml
│ └── db01.yml
└── templates/
Dynamic Variables per Environment
# group_vars/all.yml
app_config:
production:
debug: false
log_level: warn
replicas: 3
staging:
debug: true
log_level: debug
replicas: 1
current_config: "{{ app_config[env] }}"
FAQ
Where should I put group_vars — next to inventory or playbook?
Both locations work. Ansible checks group_vars/ next to the inventory file AND next to the playbook. For multi-environment setups, keep them with the inventory. For single-inventory projects, put them at the project root.
Can I use subdirectories inside group_vars?
Yes. group_vars/webservers/ (a directory) works the same as group_vars/webservers.yml (a file). All YAML files in the directory are loaded and merged. Use directories when you want to separate vault files from plain vars.
How do I set variables for a child group?
If webservers is a child of linux, variables in group_vars/linux.yml apply to webservers too. Child group vars override parent group vars.
What's the difference between hostvars and host_vars?
host_vars/ is a directory for storing per-host variable files. hostvars is a runtime variable in Ansible that lets you access any host's variables during playbook execution: hostvars['hostname'].variable_name.
Conclusion
Use group_vars/all.yml for shared defaults, group_vars/ for group-specific settings, and host_vars/ for per-host overrides. Split sensitive data into vault-encrypted files using the directory format. This keeps your inventory clean and your secrets separate from plain configuration.
Related Articles
• Ansible Inventory Guide • Ansible Vault Deep Dive • Ansible set_fact vs vars vs extra_vars • Ansible gather_facts GuideCategory: linux-administration