Ansible Host Groups & Variables
Host grouping and variables are the two features that transform a simple list of servers into a structured, manageable representation of your infrastructure. This lesson teaches you to organise hosts into meaningful groups and attach the right variables to the right hosts — skills that directly affect how clean and maintainable your playbooks will be.
Why Groups Matter
Groups are the primary mechanism for applying tasks selectively. Without groups, every playbook would either run on all hosts or require you to manually specify individual IP addresses. With groups, you write a play that targets webservers and it automatically applies to every current and future host in that group — including new hosts you add to the group months from now.
Good group design mirrors the functional architecture of your infrastructure. Common grouping strategies include:
- By function: webservers, databases, loadbalancers, monitoring
- By environment: production, staging, development, testing
- By geography: us-east, eu-west, ap-southeast
- By OS: ubuntu, centos, debian
These strategies can be combined. A single host can belong to multiple groups simultaneously — web01 might be in webservers, production, and us-east all at once.
Nested Groups with children
The :children syntax creates parent groups that aggregate child groups:
[webservers] web01 ansible_host=10.0.1.10 web02 ansible_host=10.0.1.11 [databases] db01 ansible_host=10.0.2.10 [production:children] webservers databases [staging] staging-web01 ansible_host=10.1.1.10 staging-db01 ansible_host=10.1.2.10 [all_web:children] webservers staging
This structure lets you target the entire production tier with ansible production -m ping, or all web servers across environments with ansible all_web. The nesting can go multiple levels deep for complex multi-region, multi-environment architectures.
Group Variables
Group variables apply to every host in a group. They are the right place to store settings that are consistent across a group but different between groups — for example, the web server port, the database connection string, or the monitoring endpoint URL.
Inline group variables in the inventory file:
[webservers:vars] http_port=80 max_clients=200 document_root=/var/www/html [databases:vars] db_port=5432 backup_enabled=true
Group variables in separate files (recommended for maintainability):
Create a group_vars/ directory alongside your inventory file. Inside, create one YAML file per group, named exactly after the group:
group_vars/ webservers.yml databases.yml all.yml
The contents of group_vars/webservers.yml:
http_port: 80 max_clients: 200 document_root: /var/www/html nginx_worker_processes: auto
Ansible automatically reads these files and makes the variables available to any host in the corresponding group. The separate-file approach keeps the inventory file focused on host definitions and moves complex variable data to dedicated, clearly-named files.
Host Variables
Host variables apply to a single specific host. Use them for settings that are genuinely unique per host — a specific IP binding, a custom port, a host-specific certificate path, or hardware-specific tuning parameters.
Inline in the inventory file:
[webservers] web01 ansible_host=10.0.1.10 http_port=8080 is_primary=true web02 ansible_host=10.0.1.11 http_port=80 is_primary=false
In host_vars files (recommended):
host_vars/ web01.yml web02.yml db01.yml
Contents of host_vars/web01.yml:
http_port: 8080 is_primary: true ssl_certificate: /etc/ssl/certs/web01.pem backup_schedule: "0 2 * * *"
Variable Precedence
When the same variable is defined at multiple levels, Ansible uses a specific precedence order. From lowest to highest priority:
- Inventory file
[all:vars]— lowest priority - Inventory group variables (
group_vars/all.yml) - Specific group variables (
group_vars/webservers.yml) - Host variables (
host_vars/web01.yml) - Playbook
vars:— higher priority - Extra vars (
ansible-playbook -e) — highest priority
This hierarchy lets you set sensible defaults at the group level and override them for specific hosts or at runtime without modifying the baseline configuration. For example, set http_port: 80 in group_vars/webservers.yml and override it to 8443 only in host_vars/web01.yml.
Special Connection Variables
Several variable names are reserved by Ansible for controlling how connections are made:
ansible_host— The IP or hostname to connect toansible_port— The SSH port (default: 22)ansible_user— The remote usernameansible_ssh_private_key_file— Path to the SSH private keyansible_become— Whether to use privilege escalation (true/false)ansible_become_method— How to escalate (sudo, su, etc.)ansible_python_interpreter— Path to Python on the managed node
These can be set at any level of the variable hierarchy — per host, per group, or globally. Setting ansible_user: ubuntu in group_vars/all.yml means all hosts connect as the ubuntu user unless a more specific variable overrides it.
Try This: Structure Your Lab Inventory with Variables
In your lab directory, create the full directory structure:
inventory/
hosts.ini
group_vars/
all.yml
webservers.yml
databases.yml
host_vars/
web01.ymlIn all.yml, set ansible_user and ansible_ssh_private_key_file. In webservers.yml, set http_port: 80. In host_vars/web01.yml, override http_port: 8080. Then run ansible-inventory -i inventory/ --host web01 and confirm that http_port shows as 8080 for web01 but 80 for web02.
Summary
Host grouping allows selective targeting of playbooks against logical subsets of infrastructure. Group variables apply consistently to all members of a group; host variables override settings for individual hosts. The group_vars/ and host_vars/ directory conventions keep inventory clean and maintainable. Variable precedence rules govern which value wins when the same variable is defined at multiple levels.
