Dynamic Inventory & Testing with Molecule

Ansible

Chapter 9 · Dynamic Inventory & Testing with Molecule

Two remaining practical topics before the capstone: keeping an inventory accurate automatically, and actually testing a role rather than trusting it by inspection. Both echo themes this course has already built toward — obs1-3/obs1-10's own static-vs-dynamic discovery material, applied here to hosts, and ansible1-6's own manual idempotency-testing habit, automated.

The Problem With Static Inventory at Real Scale

ansible1-3's static INI/YAML inventory is fine for a small, stable set of hosts. It breaks down the exact same way obs1-3's own static Prometheus scrape configuration did: cloud instances autoscale, get replaced, get new IPs — a hand-maintained inventory file quietly goes stale, listing hosts that no longer exist and missing ones that do.

Dynamic Inventory — Querying the Source of Truth Directly

ansible-playbook -i aws_ec2.yml site.yml

A dynamic inventory is a plugin that queries a live source — a cloud provider's API, a Kubernetes cluster — at run time, generating the inventory on the fly instead of reading a static file. aws_ec2.yml above isn't a host list; it's a plugin configuration:

plugin: amazon.aws.aws_ec2 regions: - us-east-1 filters: tag:Environment: production keyed_groups: - key: tags.Role prefix: role

This generates groups automatically from the cloud provider's own tags — any EC2 instance tagged Role=webserver lands in a role_webserver group automatically, no one maintaining that membership by hand. This is genuinely the same idea as obs1-10's own ServiceMonitor label-matching — declare what to select, let the platform's own live state populate the result — just applied to hosts instead of scrape targets.

Kubernetes as a Dynamic Inventory Source

The kubernetes.core.k8s inventory plugin generates an inventory directly from pods or services running in a cluster, pairing directly with obs1-10's own Kubernetes material — the same "don't hand-maintain a list of things that are inherently ephemeral" lesson, applied one layer further.

Testing Ansible with Molecule

ft1-1's own principle — test behavior, not implementation — applies here too. Molecule is the standard tool for testing Ansible roles: it spins up an isolated test instance (commonly via Docker), applies the role, and runs verification checks, all automatically, with no real staging server required.

molecule init role my_role molecule test

molecule init role scaffolds a testable role with its own molecule/ directory — converge.yml applies the role under test, verify.yml checks the result. molecule test runs the full cycle automatically: create a test instance → converge (apply the role) → an idempotence check → verify → destroy.

Molecule's Idempotence Check — Automating Chapter 6's Own Practice

ansible1-6 taught running a playbook twice by hand and checking for changed=0. Molecule's own idempotence step in molecule test does exactly this, automatically — applying the role a second time and failing the test outright if anything reports changed. The same discipline from that chapter, now a real, repeatable, CI-runnable check rather than a manual habit someone has to remember to perform.

Accuracy over timeSetup effort
Static inventoryGoes stale as hosts scale/changeMinimal — a plain file
Dynamic inventoryAlways reflects the live platform's own current stateRequires plugin config, API credentials
molecule test belongs in CI
Exactly the kind of check that fits tf1-10's and pipelines1's own CI material — running molecule test automatically on every role change catches a broken or non-idempotent role before it's ever applied to a real host, the same "catch it before it ships" discipline this course has already applied elsewhere.
A dynamic inventory query is a real network dependency, not a free abstraction
Every run against a live API has real cost and latency, and depends on that API being reachable and correctly authenticated — a genuine new failure mode static inventory never had (a plain file can't have an API outage). Worth being aware of, and caching where appropriate, rather than assuming a dynamic inventory query is free.

Hands-On Exercises

Exercise 1

Explain why a static inventory file listing EC2 instances by IP address would become inaccurate within days on a team using autoscaling groups, and how a dynamic inventory plugin avoids that problem.

📄 View solution
Exercise 2

Explain what molecule test's idempotence step is actually doing, and how it relates directly to the manual "run it twice, check changed=0" practice from ansible1-6.

📄 View solution
Exercise 3

A team's dynamic inventory query starts failing intermittently because the cloud API it depends on occasionally times out. Explain why this is a genuinely new category of failure compared to a static inventory file, and one mitigation worth considering.

📄 View solution

Chapter 9 Quick Reference

  • Static inventory goes stale as hosts autoscale/get replaced — the same problem obs1-3's own static scrape config had
  • Dynamic inventory plugins query a live source (cloud API, Kubernetes) at run time, generating groups automatically from tags/labels
  • The kubernetes.core.k8s plugin applies the same idea directly to a Kubernetes cluster, pairing with obs1-10
  • Molecule tests roles in isolation — create, converge, idempotence check, verify, destroy — automatically
  • Molecule's own idempotence step automates ansible1-6's own manual "run twice, expect changed=0" practice
  • molecule test belongs in CI — catching a broken role before it ever touches a real host
  • A dynamic inventory query is a real network dependency — it can fail in ways a static file never could