Introduction
Ansible hostvars are essential variables that store information about each managed host in your infrastructure. These variables enable you to create dynamic, flexible automation workflows that adapt to different servers and environments.
In this hands-on lab, you will learn how to work with Ansible hostvars from the ground up. You will set up a simple inventory, access hostvars in playbooks, use them in templates, and explore practical use cases. By the end of this lab, you will understand how to leverage hostvars to make your Ansible automation more powerful and adaptable.
Setting Up the Lab Environment
Before diving into Ansible hostvars, we need to set up our working environment. In this step, we will install Ansible, create a project directory structure, and prepare our inventory file.
Installing Ansible
Let's start by installing Ansible on our system:
sudo apt update
sudo apt install -y ansible
After installation, verify that Ansible is installed correctly:
ansible --version
You should see output similar to this:
ansible [core 2.12.x]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.x (default, Mar 15 2023, 11:42:32) [GCC 11.3.0]
jinja version = 3.0.3
libyaml = True
Creating the Project Structure
Now, let's create a proper directory structure for our Ansible project:
mkdir -p ~/project/ansible_hostvars/inventory
mkdir -p ~/project/ansible_hostvars/group_vars
mkdir -p ~/project/ansible_hostvars/playbooks
mkdir -p ~/project/ansible_hostvars/templates
cd ~/project/ansible_hostvars
Creating an Inventory File
Ansible uses inventory files to define the hosts and groups it will manage. Let's create a simple inventory file with some example hosts:
cat > ~/project/ansible_hostvars/inventory/hosts << 'EOF'
[webservers]
web01 ansible_host=192.168.1.10 http_port=80 max_connections=100
web02 ansible_host=192.168.1.11 http_port=8080 max_connections=200
[dbservers]
db01 ansible_host=192.168.1.20 db_port=3306 backup_dir=/var/backups
db02 ansible_host=192.168.1.21 db_port=5432 backup_dir=/opt/backups
[all:vars]
ansible_connection=local
ansible_user=labex
environment=development
EOF
In this inventory file:
- We've defined two groups:
webserversanddbservers - Each host has specific variables like
http_portordb_port - We've set global variables for all hosts under
[all:vars] - We're using
ansible_connection=localsince this is a lab environment
Let's also create a simple ansible.cfg file in our project directory:
cat > ~/project/ansible_hostvars/ansible.cfg << 'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
EOF
Now, let's verify our inventory:
cd ~/project/ansible_hostvars
ansible-inventory --list
You should see a JSON output displaying all the hosts and their variables in your inventory.
Congratulations! You've successfully set up your Ansible environment and created an inventory with host variables. In the next step, we'll explore how to access these variables using hostvars.
Exploring Ansible Hostvars
Now that we have our environment set up, let's explore Ansible hostvars and learn how to access them in playbooks.
Understanding Hostvars
In Ansible, hostvars is a special variable that contains information about all hosts in your inventory. It's a dictionary where the keys are hostnames and the values are dictionaries containing all variables defined for each host.
Let's create a simple playbook to explore hostvars:
cat > ~/project/ansible_hostvars/playbooks/explore_hostvars.yml << 'EOF'
---
- name: Explore hostvars
hosts: all
gather_facts: no
tasks:
- name: Display host variables for the current host
debug:
msg: "Host: {{ inventory_hostname }} has the following variables: {{ hostvars[inventory_hostname] }}"
- name: Display a specific variable for the current host
debug:
msg: "Host {{ inventory_hostname }} has environment: {{ hostvars[inventory_hostname]['environment'] }}"
EOF
Now, let's run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/explore_hostvars.yml
You should see output with each host's variables. The first task shows all variables for each host, while the second task shows a specific variable.
Creating a Host-Specific Variables Playbook
Let's create another playbook that demonstrates how to access different types of host variables:
cat > ~/project/ansible_hostvars/playbooks/host_specific_vars.yml << 'EOF'
---
- name: Working with host-specific variables
hosts: all
gather_facts: no
tasks:
- name: Display web server information
debug:
msg: "Web server {{ inventory_hostname }} running on port {{ hostvars[inventory_hostname]['http_port'] | default('N/A') }}"
when: inventory_hostname in groups['webservers']
- name: Display database server information
debug:
msg: "Database server {{ inventory_hostname }} running on port {{ hostvars[inventory_hostname]['db_port'] | default('N/A') }}"
when: inventory_hostname in groups['dbservers']
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/host_specific_vars.yml
You should see output that shows different information for web servers and database servers, based on their respective variables.
Accessing Variables from Other Hosts
One of the powerful features of hostvars is that you can access variables from any host in your inventory. Let's create a playbook that demonstrates this:
cat > ~/project/ansible_hostvars/playbooks/cross_host_vars.yml << 'EOF'
---
- name: Access variables from other hosts
hosts: web01
gather_facts: no
tasks:
- name: Display information about web01 and db01
debug:
msg: |
Web server: {{ inventory_hostname }}
Web server port: {{ hostvars[inventory_hostname]['http_port'] }}
Database server: db01
Database port: {{ hostvars['db01']['db_port'] }}
Backup directory: {{ hostvars['db01']['backup_dir'] }}
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/cross_host_vars.yml
You should see output that shows information from both web01 and db01, even though the playbook is only running on web01.
This demonstrates how hostvars give you access to variables from all hosts in your inventory, enabling you to create complex relationships and dependencies between hosts in your automation.
Using Hostvars in Templates
Templates are one of the most powerful features in Ansible, and they become even more powerful when combined with hostvars. In this step, we'll learn how to use hostvars within Jinja2 templates to create dynamic configuration files.
Introduction to Jinja2 Templates
Ansible uses the Jinja2 templating engine to generate dynamic content. Templates allow you to create configuration files that adapt to different hosts and scenarios.
Let's create a simple web server configuration template:
mkdir -p ~/project/ansible_hostvars/templates
cat > ~/project/ansible_hostvars/templates/nginx.conf.j2 << 'EOF'
## Server configuration for {{ inventory_hostname }}
## Generated by Ansible
server {
listen {{ hostvars[inventory_hostname]['http_port'] | default(80) }};
server_name {{ inventory_hostname }};
root /var/www/html;
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
## Max connections: {{ hostvars[inventory_hostname]['max_connections'] | default(50) }}
location / {
index index.html index.htm;
}
}
EOF
Now, let's create a database configuration template:
cat > ~/project/ansible_hostvars/templates/db.conf.j2 << 'EOF'
## Database configuration for {{ inventory_hostname }}
## Generated by Ansible
port = {{ hostvars[inventory_hostname]['db_port'] }}
backup_directory = {{ hostvars[inventory_hostname]['backup_dir'] }}
environment = {{ hostvars[inventory_hostname]['environment'] }}
## Database hosts in environment:
{% for host in groups['dbservers'] %}
## - {{ host }} ({{ hostvars[host]['ansible_host'] }})
{% endfor %}
EOF
Creating a Playbook to Apply Templates
Let's create a playbook that applies these templates:
cat > ~/project/ansible_hostvars/playbooks/apply_templates.yml << 'EOF'
---
- name: Apply configuration templates
hosts: all
gather_facts: no
tasks:
- name: Create output directory
file:
path: ~/project/ansible_hostvars/output
state: directory
run_once: true
- name: Apply web server configuration template
template:
src: ../templates/nginx.conf.j2
dest: ~/project/ansible_hostvars/output/{{ inventory_hostname }}-nginx.conf
when: inventory_hostname in groups['webservers']
- name: Apply database configuration template
template:
src: ../templates/db.conf.j2
dest: ~/project/ansible_hostvars/output/{{ inventory_hostname }}-db.conf
when: inventory_hostname in groups['dbservers']
EOF
Now, let's run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/apply_templates.yml
After running the playbook, check the generated configuration files:
ls -l ~/project/ansible_hostvars/output/
You should see configuration files generated for each host. Let's examine one of the web server configurations:
cat ~/project/ansible_hostvars/output/web01-nginx.conf
And one of the database configurations:
cat ~/project/ansible_hostvars/output/db01-db.conf
Notice how the templates use hostvars to dynamically generate configurations tailored to each host.
Using Loops and Conditionals in Templates
Templates can use loops and conditionals to create even more dynamic content. Let's create a comprehensive hosts file template:
cat > ~/project/ansible_hostvars/templates/hosts.j2 << 'EOF'
## Hosts file generated by Ansible
127.0.0.1 localhost
## Web servers
{% for host in groups['webservers'] %}
{{ hostvars[host]['ansible_host'] }} {{ host }}
{% endfor %}
## Database servers
{% for host in groups['dbservers'] %}
{{ hostvars[host]['ansible_host'] }} {{ host }}
{% endfor %}
EOF
Let's add a task to our playbook to apply this template:
cat > ~/project/ansible_hostvars/playbooks/hosts_template.yml << 'EOF'
---
- name: Create hosts file from template
hosts: localhost
gather_facts: no
tasks:
- name: Create output directory
file:
path: ~/project/ansible_hostvars/output
state: directory
- name: Generate hosts file
template:
src: ../templates/hosts.j2
dest: ~/project/ansible_hostvars/output/hosts
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/hosts_template.yml
Check the generated hosts file:
cat ~/project/ansible_hostvars/output/hosts
You should see a hosts file with all your webservers and dbservers, generated dynamically from your inventory.
Advanced Hostvars Techniques
Now that you've mastered the basics of hostvars, let's explore some advanced techniques for working with them in Ansible.
Using Group Variables with Hostvars
Group variables allow you to define variables that apply to entire groups of hosts. Let's create a group variables file in the correct location within our inventory directory:
mkdir -p ~/project/ansible_hostvars/inventory/group_vars
cat > ~/project/ansible_hostvars/inventory/group_vars/webservers.yml << 'EOF'
---
web_server_type: nginx
default_document_root: /var/www/html
enable_ssl: true
ssl_cert_path: /etc/ssl/certs
EOF
And another for the database servers:
cat > ~/project/ansible_hostvars/inventory/group_vars/dbservers.yml << 'EOF'
---
backup_frequency: daily
backup_retention: 7
monitoring_enabled: true
alert_email: admin@example.com
EOF
Now, let's create a playbook that accesses these group variables through hostvars:
cat > ~/project/ansible_hostvars/playbooks/group_vars_demo.yml << 'EOF'
---
- name: Demonstrate group variables with hostvars
hosts: all
gather_facts: no
tasks:
- name: Display web server group variables
debug:
msg: |
Host: {{ inventory_hostname }}
Web Server Type: {{ hostvars[inventory_hostname]['web_server_type'] | default('N/A') }}
Document Root: {{ hostvars[inventory_hostname]['default_document_root'] | default('N/A') }}
SSL Enabled: {{ hostvars[inventory_hostname]['enable_ssl'] | default('N/A') }}
when: inventory_hostname in groups['webservers']
- name: Display database server group variables
debug:
msg: |
Host: {{ inventory_hostname }}
Backup Frequency: {{ hostvars[inventory_hostname]['backup_frequency'] | default('N/A') }}
Backup Retention: {{ hostvars[inventory_hostname]['backup_retention'] | default('N/A') }}
Monitoring Enabled: {{ hostvars[inventory_hostname]['monitoring_enabled'] | default('N/A') }}
when: inventory_hostname in groups['dbservers']
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/group_vars_demo.yml
You should see output showing how group variables are available through hostvars.
Creating Dynamic Inventory Reports
Let's create a playbook that generates reports based on inventory data:
cat > ~/project/ansible_hostvars/playbooks/inventory_report.yml << 'EOF'
---
- name: Generate inventory reports
hosts: localhost
gather_facts: no
tasks:
- name: Create output directory
file:
path: ~/project/ansible_hostvars/output
state: directory
- name: Generate web servers report
template:
src: ../templates/web_report.j2
dest: ~/project/ansible_hostvars/output/web_servers_report.txt
- name: Generate database servers report
template:
src: ../templates/db_report.j2
dest: ~/project/ansible_hostvars/output/db_servers_report.txt
EOF
Now, let's create the templates for these reports:
cat > ~/project/ansible_hostvars/templates/web_report.j2 << 'EOF'
========================================
WEB SERVERS INVENTORY REPORT
========================================
{% for host in groups['webservers'] %}
HOST: {{ host }}
IP Address: {{ hostvars[host]['ansible_host'] }}
HTTP Port: {{ hostvars[host]['http_port'] }}
Max Connections: {{ hostvars[host]['max_connections'] | default('Not specified') }}
Web Server Type: {{ hostvars[host]['web_server_type'] | default('Not specified') }}
Environment: {{ hostvars[host]['environment'] }}
{% endfor %}
EOF
cat > ~/project/ansible_hostvars/templates/db_report.j2 << 'EOF'
========================================
DATABASE SERVERS INVENTORY REPORT
========================================
{% for host in groups['dbservers'] %}
HOST: {{ host }}
IP Address: {{ hostvars[host]['ansible_host'] }}
DB Port: {{ hostvars[host]['db_port'] }}
Backup Directory: {{ hostvars[host]['backup_dir'] }}
Backup Frequency: {{ hostvars[host]['backup_frequency'] | default('Not specified') }}
Backup Retention: {{ hostvars[host]['backup_retention'] | default('Not specified') }}
Environment: {{ hostvars[host]['environment'] }}
{% endfor %}
EOF
Now, run the inventory report playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/inventory_report.yml
Check the generated reports:
cat ~/project/ansible_hostvars/output/web_servers_report.txt
cat ~/project/ansible_hostvars/output/db_servers_report.txt
These reports demonstrate how hostvars can be used to create comprehensive reports of your infrastructure.
Handling Missing Variables
When working with hostvars, it's important to handle cases where variables might be missing. Let's create a playbook that demonstrates safe variable access:
cat > ~/project/ansible_hostvars/playbooks/safe_variable_access.yml << 'EOF'
---
- name: Demonstrate safe variable access
hosts: all
gather_facts: no
tasks:
- name: Using default filter
debug:
msg: "The value is: {{ hostvars[inventory_hostname]['nonexistent_variable'] | default('Not defined') }}"
- name: Using conditional checks
debug:
msg: >
{% if 'special_variable' in hostvars[inventory_hostname] %}
The special variable is: {{ hostvars[inventory_hostname]['special_variable'] }}
{% else %}
The special variable is not defined for this host.
{% endif %}
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/safe_variable_access.yml
The output shows how to safely handle missing variables using the default filter and conditional checks.
Best Practices and Real-World Applications
In this final step, we'll explore best practices for working with hostvars and look at some real-world applications.
Best Practices for Organizing Variables
Organizing your variables properly is crucial for maintaining clean, maintainable Ansible code. Let's create a more structured inventory setup to demonstrate best practices:
mkdir -p ~/project/ansible_hostvars/inventory/group_vars/all
mkdir -p ~/project/ansible_hostvars/inventory/group_vars/webservers
mkdir -p ~/project/ansible_hostvars/inventory/group_vars/dbservers
mkdir -p ~/project/ansible_hostvars/inventory/host_vars
Now, let's create some organized variable files:
cat > ~/project/ansible_hostvars/inventory/group_vars/all/common.yml << 'EOF'
---
## Common variables for all hosts
ntp_servers:
- ntp1.example.com
- ntp2.example.com
timezone: UTC
monitoring_enabled: true
monitoring_server: monitor.example.com
EOF
cat > ~/project/ansible_hostvars/inventory/group_vars/webservers/web.yml << 'EOF'
---
## Web server specific variables
http_protocol: https
default_vhost: default.example.com
web_user: www-data
web_group: www-data
firewall_ports:
- 80
- 443
EOF
cat > ~/project/ansible_hostvars/inventory/host_vars/web01.yml << 'EOF'
---
## Host-specific variables for web01
server_role: primary
backup_server: web02
custom_vhosts:
- name: site1.example.com
docroot: /var/www/site1
- name: site2.example.com
docroot: /var/www/site2
EOF
Let's create a playbook that demonstrates accessing these structured variables:
cat > ~/project/ansible_hostvars/playbooks/structured_vars.yml << 'EOF'
---
- name: Demonstrate structured variables
hosts: localhost
gather_facts: no
tasks:
- name: Display structured variables
debug:
msg: |
Common variables:
- NTP Servers: {{ hostvars['web01']['ntp_servers'] | default([]) }}
- Timezone: {{ hostvars['web01']['timezone'] | default('Not set') }}
Web server variables:
- HTTP Protocol: {{ hostvars['web01']['http_protocol'] | default('Not set') }}
- Default VHost: {{ hostvars['web01']['default_vhost'] | default('Not set') }}
Host-specific variables for web01:
- Server Role: {{ hostvars['web01']['server_role'] | default('Not set') }}
- Backup Server: {{ hostvars['web01']['backup_server'] | default('Not set') }}
- Custom VHosts: {{ hostvars['web01']['custom_vhosts'] | default([]) }}
EOF
Run this playbook:
cd ~/project/ansible_hostvars
ANSIBLE_INVENTORY=~/project/ansible_hostvars/inventory ansible-playbook playbooks/structured_vars.yml
Note: We're using the ANSIBLE_INVENTORY environment variable to specify a different inventory path for this example.
Creating a Configuration Generator
Let's create a practical application that generates configuration files for multiple services:
mkdir -p ~/project/ansible_hostvars/templates/configs
Create template files for different services:
cat > ~/project/ansible_hostvars/templates/configs/apache.conf.j2 << 'EOF'
## Apache configuration for {{ inventory_hostname }}
Listen {{ hostvars[inventory_hostname]['http_port'] | default(80) }}
ServerName {{ inventory_hostname }}
DocumentRoot {{ hostvars[inventory_hostname]['default_document_root'] | default('/var/www/html') }}
MaxClients {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF
cat > ~/project/ansible_hostvars/templates/configs/mysql.conf.j2 << 'EOF'
## MySQL configuration for {{ inventory_hostname }}
[mysqld]
port = {{ hostvars[inventory_hostname]['db_port'] | default(3306) }}
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
max_connections = {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}
## Backup directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('/var/backups') }}
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF
cat > ~/project/ansible_hostvars/templates/configs/postgresql.conf.j2 << 'EOF'
## PostgreSQL configuration for {{ inventory_hostname }}
listen_addresses = '*'
port = {{ hostvars[inventory_hostname]['db_port'] | default(5432) }}
max_connections = {{ hostvars[inventory_hostname]['max_connections'] | default(100) }}
## Backup directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('/var/backups') }}
## Environment: {{ hostvars[inventory_hostname]['environment'] }}
EOF
Now, create a playbook to apply these templates:
cat > ~/project/ansible_hostvars/playbooks/config_generator.yml << 'EOF'
---
- name: Generate service configurations
hosts: all
gather_facts: no
tasks:
- name: Create output directory
file:
path: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}
state: directory
- name: Generate Apache configuration for web servers
template:
src: ../templates/configs/apache.conf.j2
dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/apache.conf
when: inventory_hostname in groups['webservers']
- name: Generate MySQL configuration for database servers with MySQL
template:
src: ../templates/configs/mysql.conf.j2
dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/mysql.conf
when: inventory_hostname in groups['dbservers'] and hostvars[inventory_hostname]['db_port'] | string == '3306'
- name: Generate PostgreSQL configuration for database servers with PostgreSQL
template:
src: ../templates/configs/postgresql.conf.j2
dest: ~/project/ansible_hostvars/output/configs/{{ inventory_hostname }}/postgresql.conf
when: inventory_hostname in groups['dbservers'] and hostvars[inventory_hostname]['db_port'] | string == '5432'
EOF
Run the config generator playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/config_generator.yml
Explore the generated configuration files:
find ~/project/ansible_hostvars/output/configs -type f | sort
View some of the generated configurations:
cat ~/project/ansible_hostvars/output/configs/web01/apache.conf
cat ~/project/ansible_hostvars/output/configs/db01/mysql.conf
cat ~/project/ansible_hostvars/output/configs/db02/postgresql.conf
Creating a Host Documentation Tool
Finally, let's create a tool that generates comprehensive documentation for each host in our inventory:
cat > ~/project/ansible_hostvars/templates/host_doc.j2 << 'EOF'
## Host Documentation for {{ inventory_hostname }}
==============================================
### Basic Information
- Hostname: {{ inventory_hostname }}
- IP Address: {{ hostvars[inventory_hostname]['ansible_host'] }}
- Environment: {{ hostvars[inventory_hostname]['environment'] | default('Not specified') }}
### Role Information
{% if inventory_hostname in groups['webservers'] %}
- Role: Web Server
- HTTP Port: {{ hostvars[inventory_hostname]['http_port'] | default('Not specified') }}
- Max Connections: {{ hostvars[inventory_hostname]['max_connections'] | default('Not specified') }}
{% if 'web_server_type' in hostvars[inventory_hostname] %}
- Web Server Type: {{ hostvars[inventory_hostname]['web_server_type'] }}
{% endif %}
{% endif %}
{% if inventory_hostname in groups['dbservers'] %}
- Role: Database Server
- DB Port: {{ hostvars[inventory_hostname]['db_port'] | default('Not specified') }}
- Backup Directory: {{ hostvars[inventory_hostname]['backup_dir'] | default('Not specified') }}
{% if 'backup_frequency' in hostvars[inventory_hostname] %}
- Backup Frequency: {{ hostvars[inventory_hostname]['backup_frequency'] }}
- Backup Retention: {{ hostvars[inventory_hostname]['backup_retention'] }} days
{% endif %}
{% endif %}
### Related Hosts
{% if inventory_hostname in groups['webservers'] %}
#### Database Servers:
{% for db_host in groups['dbservers'] %}
- {{ db_host }} ({{ hostvars[db_host]['ansible_host'] }})
{% endfor %}
{% endif %}
{% if inventory_hostname in groups['dbservers'] %}
#### Web Servers:
{% for web_host in groups['webservers'] %}
- {{ web_host }} ({{ hostvars[web_host]['ansible_host'] }})
{% endfor %}
{% endif %}
EOF
Create a playbook to generate the documentation:
cat > ~/project/ansible_hostvars/playbooks/host_documentation.yml << 'EOF'
---
- name: Generate host documentation
hosts: all
gather_facts: no
tasks:
- name: Create output directory
file:
path: ~/project/ansible_hostvars/output/docs
state: directory
- name: Generate host documentation
template:
src: ../templates/host_doc.j2
dest: ~/project/ansible_hostvars/output/docs/{{ inventory_hostname }}.md
EOF
Run the documentation playbook:
cd ~/project/ansible_hostvars
ansible-playbook playbooks/host_documentation.yml
View the generated documentation:
ls -l ~/project/ansible_hostvars/output/docs/
cat ~/project/ansible_hostvars/output/docs/web01.md
cat ~/project/ansible_hostvars/output/docs/db01.md
Congratulations! You've now completed a comprehensive exploration of Ansible hostvars, from basic usage to advanced applications. You've learned how to access host variables, use them in templates, and create practical tools for managing your infrastructure.
Summary
In this lab, you explored the power and versatility of Ansible hostvars. Here's what you learned:
Setting Up the Environment: You configured an Ansible environment with an inventory structure that included hosts, groups, and variables.
Exploring Hostvars: You learned how to access hostvars in playbooks, including accessing variables from the current host and from other hosts in the inventory.
Using Hostvars in Templates: You created Jinja2 templates that leverage hostvars to generate dynamic configuration files tailored to each host.
Advanced Hostvars Techniques: You explored group variables, dynamic inventory reports, and techniques for handling missing variables safely.
Best Practices and Real-World Applications: You implemented structured variable organization and created practical applications, including a configuration generator and a host documentation tool.
Ansible hostvars are a powerful feature that allows you to create dynamic, adaptable automation workflows. By understanding how to effectively work with hostvars, you can create more flexible and maintainable automation solutions for your infrastructure.
As you continue your Ansible journey, remember that hostvars are just one part of Ansible's rich ecosystem of features. Consider exploring other features like roles, collections, and dynamic inventories to further enhance your automation capabilities.


