How to Mock an Ansible Inventory in Python

Load an Ansible-style inventory JSON file into Python and simulate a playbook run across hosts and groups.

Easy Python 3.9+ Aug 9, 2026 Automation & scripting 12 views 0 copies

Python code

52 lines
Python 3.9+
import json
from pathlib import Path


class InventoryMock:
    def __init__(self, inventory_file: str):
        self.inventory_file = Path(inventory_file)
        self.hosts = {}

    def load(self):
        if not self.inventory_file.exists():
            raise FileNotFoundError(f"Inventory file {self.inventory_file} not found")
        with open(self.inventory_file) as f:
            data = json.load(f)
        for group, details in data.get("all", {}).get("children", {}).items():
            for host in details.get("hosts", {}):
                self.hosts[host] = {
                    "group": group,
                    **details["hosts"][host].get("vars", {})
                }
        return self

    def run_playbook(self, playbook: str):
        print(f"Running playbook: {playbook}")
        for host, vars_data in self.hosts.items():
            print(f"  -> {host}: {vars_data}")


if __name__ == "__main__":
    inventory = {
        "all": {
            "children": {
                "web": {
                    "hosts": {
                        "web1": {"vars": {"port": 8080, "role": "nginx"}},
                        "web2": {"vars": {"port": 8081, "role": "nginx"}}
                    }
                },
                "db": {
                    "hosts": {
                        "db1": {"vars": {"port": 5432, "role": "postgres"}}
                    }
                }
            }
        }
    }
    with open("inventory.json", "w") as f:
        json.dump(inventory, f)

    mock = InventoryMock("inventory.json")
    mock.load()
    mock.run_playbook("setup.yml")

Output

stdout
Running playbook: setup.yml
  -> web1: {'group': 'web', 'port': 8080, 'role': 'nginx'}
  -> web2: {'group': 'web', 'port': 8081, 'role': 'nginx'}
  -> db1: {'group': 'db', 'port': 5432, 'role': 'postgres'}

How it works

This class reads an Ansible-style inventory JSON where hosts are nested under 'all' > 'children' groups. It flattens each host into a dict that includes its group name and any group-level or host-level vars. The load method validates the file exists and raises a clear error otherwise. Leaving hosts as an empty dict in __init__ makes the class reusable across multiple inventory files. The run_playbook method simulates execution by iterating hosts and printing their resolved variables, which is useful for testing automation logic without a real Ansible environment.

Common mistakes

  • Assuming the inventory file path is relative to the current working directory instead of using an absolute path.
  • Forgetting to handle missing `vars` keys — use `.get('vars', {})` to avoid KeyError.
  • Not resetting `self.hosts` between loads, which can leave stale data when reusing the instance.
  • Hardcoding the inventory structure instead of checking for empty or malformed JSON.

Variations

  1. Use `json.loads` with a string instead of a file if the inventory is fetched from an API or command output.
  2. Add a `--list` CLI flag using `argparse` to print host groups without running a playbook.

Real-world use cases

  • Test automation scripts locally without needing a live Ansible control node or SSH access to servers.
  • Validate inventory grouping and variable inheritance before deploying to a production cluster.
  • Generate compliance reports by mapping hosts to their assigned roles and ports from a versioned inventory file.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.