Unlocking Ansible: Accessing host_vars and group_vars in a Python Scripts

Exploring how to access host_vars and group_vars in Python scripts for enhanced Ansible automation.

Unlocking Ansible: Accessing host_vars and group_vars in a Python Scripts

Welcome to the world of Ansible magic! In this blog post, we're going to uncover the secrets of accessing host_vars and group_vars directly from Python scripts. These variables hold the keys to customizing your automation scripts, empowering you to unlock new levels of flexibility and efficiency in your infrastructure management.

Let’s dive in!

To do this, we’ll use the Ansible API. The Ansible API is a powerful tool that allows you to interact with Ansible programmatically. The documentation for the Ansible API can be found here.

Ansible Project Structure

My ansible project folder structure looks like this

.
├── ansible.cfg
├── ansible_pyapi.py
├── group_vars
│   ├── all.yaml
│   └── host1_2.yaml
├── host_vars
│   ├── host1.yml
│   ├── host2.yml
│   └── host3.yml
└── inventory.ini

folder structure

Inventory File

My inventory file looks like this:

host1
host2
host3

[host1_2]
host1
host2

[all:vars]
username= "username"
password= "password"

inventory.ini

Host Vars and Group Vars

Contents of host_vars and group_vars files are as follows:

host_vars_location: from host_vars/host1.yml

host_vars/host1.yml

host_vars_location: from host_vars/host2.yml

host_vars/host2.yml

host_vars_location: from host_vars/host3.yml

host_vars/host3.yml

all_group_vars: from group_vars/all.yaml

group_vars/all.yml

group_vars_location: from group_vars/host1_2.yaml

group_vars/host1_2.yml

Accessing Ansible Variables in Python

Now, let’s write a Python script that accesses the host_vars and group_vars from the Ansible project. Refer to the comments in the code for a detailed explanation.

from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from rich import print as rprint

# Takes care of finding and reading yaml, json and ini files
loader = DataLoader()
# create inventory uses the inventory file passes as source or hosts in a comma separated string
inventory = InventoryManager(loader=loader, sources="./inventory.ini")
# variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
vm = VariableManager(loader=loader, inventory=inventory)

# Get all the hosts in the inventory
hosts = inventory.get_hosts()

# Access the Vars for each host, this is a collection of all the vars in the host_vars and group_vars for a particular host
for host in hosts:
    host_vars = vm.get_vars(host=host)
    print(host_vars)

python script

The output of the above script is:

Variables for host: host3
{
    'username': 'username',
    'password': 'password',
    'all_group_vars': 'from group_vars/all.yaml',
    'inventory_file': '**redacted**/inventory.ini',
    'inventory_dir': '**redacted**',
    'inventory_hostname': 'host3',
    'inventory_hostname_short': 'host3',
    'group_names': ['ungrouped'],
    'host_vars_location': 'from host_vars/host3.yml',
    'ansible_facts': {},
    'playbook_dir': '**redacted**',
    'ansible_playbook_python': '**redacted**/bin/python',
    'ansible_config_file': '**redacted**/ansible.cfg',
    'groups': {'all': ['host3', 'host1', 'host2'], 'ungrouped': ['host3'], 'host1_2': ['host1', 'host2']},
    'omit': '__omit_place_holder__99310f95566d97350e9b3dab7238e2fff4fa596a',
    'ansible_version': 'Unknown'
}
Variables for host: host1
{
    'username': 'username',
    'password': 'password',
    'all_group_vars': 'from group_vars/all.yaml',
    'group_vars_location': 'from group_vars/host1_2.yaml',
    'inventory_file': '**redacted**/inventory.ini',
    'inventory_dir': '**redacted**',
    'inventory_hostname': 'host1',
    'inventory_hostname_short': 'host1',
    'group_names': ['host1_2'],
    'host_vars_location': 'from host_vars/host1.yml',
    'ansible_facts': {},
    'playbook_dir': '**redacted**',
    'ansible_playbook_python': '**redacted**/bin/python',
    'ansible_config_file': '**redacted**/ansible.cfg',
    'groups': {'all': ['host3', 'host1', 'host2'], 'ungrouped': ['host3'], 'host1_2': ['host1', 'host2']},
    'omit': '__omit_place_holder__99310f95566d97350e9b3dab7238e2fff4fa596a',
    'ansible_version': 'Unknown'
}
Variables for host: host2
{
    'username': 'username',
    'password': 'password',
    'all_group_vars': 'from group_vars/all.yaml',
    'group_vars_location': 'from group_vars/host1_2.yaml',
    'inventory_file': '**redacted**/inventory.ini',
    'inventory_dir': '**redacted**',
    'inventory_hostname': 'host2',
    'inventory_hostname_short': 'host2',
    'group_names': ['host1_2'],
    'host_vars_location': 'from host_vars/host2.yml',
    'ansible_facts': {},
    'playbook_dir': '**redacted**',
    'ansible_playbook_python': '**redacted**/bin/python',
    'ansible_config_file': '**redacted**/ansible.cfg',
    'groups': {'all': ['host3', 'host1', 'host2'], 'ungrouped': ['host3'], 'host1_2': ['host1', 'host2']},
    'omit': '__omit_place_holder__99310f95566d97350e9b3dab7238e2fff4fa596a',
    'ansible_version': 'Unknown'
}

output

Taking a closer look at the output, you can see that the script successfully has merged the host_vars and group_vars for each host. The group_vars_location variable is available only for hosts that are part of the host1_2 group.

Conclusion

In this blog post, we have explored how to access host_vars and group_vars from an Ansible project within a Python script. This is a powerful technique that can be used to enhance your automation workflows. I hope you found this post helpful.

Here’s to smoother automation and happier coding! 🍺🍻🍺🍻