Skip to content
CloudOps
Newsletter
All guides
AI for Ansible By James Joyner IV · · 11 min read

Managing Ansible Galaxy Dependencies and requirements.yml with AI

Use AI to audit Ansible Galaxy requirements.yml, pin role and collection versions, tame transitive dependencies, and keep your supply chain trustworthy.

  • #iac
  • #ansible
  • #supply-chain
  • #automation

The build had been green for four months. Then, on a sleepy Tuesday afternoon, a routine ansible-galaxy install -r requirements.yml in our CI pipeline pulled down a brand-new major version of a community PostgreSQL role, and our staging provision blew up with a cryptic 'become_user' is undefined. Nobody had touched the playbook. Nobody had touched the role. What changed was that the upstream maintainer cut a release, and our requirements file said, in effect, give me whatever is newest. We had no version pin. We had no lockfile. We had a 90-minute outage and a very awkward standup.

That afternoon convinced me to treat requirements.yml with the same seriousness I give a package-lock.json or a Terraform lockfile. And once I started auditing dependency files with an AI assistant looking over my shoulder, I found problems I had walked past for years. Here is how I do it now — and where AI helps, where it absolutely must not.

Why requirements.yml Is a Supply-Chain Surface

Ansible Galaxy is wonderful: thousands of community roles and collections, one command to install them. It is also a fat slice of your software supply chain that most teams never review. Every role you pull executes tasks as root on your hosts. Every collection ships Python that runs on your control node. An unpinned dependency is a standing invitation for an upstream change — benign or malicious — to walk straight into production.

Two kinds of artifacts live in this file, and they behave differently:

  • Roles — the classic unit, installed into roles/. Can come from Galaxy, a git repo, or a tarball URL.
  • Collections — the modern packaging format (modules, plugins, roles bundled together), installed into collections/.

A combined requirements.yml looks like this:

---
roles:
  - name: "geerlingguy.postgresql"
    version: "3.5.2"
  - name: "internal.hardening"
    src: "git+https://git.example.com/ansible/hardening.git"
    version: "v2.4.0"

collections:
  - name: "community.general"
    version: "8.6.0"
  - name: "ansible.posix"
    version: "1.5.4"

Note the colons inside the src URL and the quoting around every value — YAML will happily misread an unquoted git+https://... or a bare version like 3.10 (which it parses as a float, dropping the trailing zero). Quote your strings.

Pin Everything, Always

The single highest-leverage habit is version pinning. Galaxy supports exact tags, and for git sources you can pin to a tag, branch, or — best of all — a commit SHA:

---
roles:
  - name: "geerlingguy.docker"
    version: "7.4.5"
  - name: "internal.networking"
    src: "git+https://git.example.com/ansible/networking.git"
    # A SHA is immutable; a tag can be re-pushed, a branch always moves.
    version: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"

collections:
  - name: "kubernetes.core"
    version: "5.0.0"
  - name: "community.docker"
    version: "3.10.4"

A floating tag can be force-pushed over. A branch moves every commit. A SHA is the only truly reproducible reference for a git source — treat it as your lockfile entry. For Galaxy-hosted content, an exact version is immutable by policy, so an exact tag is enough.

This is exactly the kind of tedious, mechanical audit where an AI assistant earns its keep. Paste your requirements.yml into a tool like Claude or Cursor and ask it to flag every entry that lacks a version, every git source pinned to a branch instead of a tag or SHA, and every version that YAML might coerce to a number. It is fast, it is thorough, and it never gets bored on entry 47 of 60.

Pro Tip: Ask the AI to rewrite your file with pins set to the currently installed versions, then run ansible-galaxy collection list and ansible-galaxy role list to confirm the numbers match what is actually on disk. Pinning to a version you have never tested is just a different flavor of risk.

A Prompt That Audits for You

The audit is repeatable, so make it a saved prompt. Here is the shape I use (keep your own copy in a prompt workspace or grab a ready-made one from the prompts library):

You are reviewing an Ansible requirements.yml. List, as a table: (1) every role or collection with no version, (2) every git src pinned to a branch or HEAD rather than a tag or commit SHA, (3) any version value that is unquoted and could be parsed as a number, and (4) any source that is not on an allow-list I will provide. Do NOT install anything. Do NOT invent version numbers — if you do not know the latest safe version, say so and tell me how to check.

That last sentence matters. An AI will, if you let it, confidently fill in a “latest” version that does not exist or that it half-remembers. Treat every suggested number as unverified until you have checked it against Galaxy or the upstream repo yourself.

Transitive Dependency Hell and meta/main.yml

Roles can depend on other roles through meta/main.yml, and those dependencies install automatically and recursively. This is where reproducibility quietly dies:

---
galaxy_info:
  role_name: "app_server"
  author: "platform-team"
  description: "Provisions the application tier"
  min_ansible_version: "2.15"
  license: "MIT"

dependencies:
  - role: "geerlingguy.nginx"
    version: "3.2.0"
  - role: "geerlingguy.certbot"
    version: "5.1.1"

If you omit version here, a transitive role floats just like a top-level one — except it is one level removed, so nobody notices until it breaks. AI is genuinely useful for tracing these chains: hand it the meta/main.yml files across your roles and ask it to build the full dependency graph and flag every unpinned edge. It will spot the orphaned transitive dep you forgot existed.

But — and I cannot stress this enough — AI suggesting a dependency is added is a different and far riskier act than AI tidying one that already exists. Pinning a version you already trust is low-stakes. Introducing a new role from the internet because the assistant recommended it is a supply-chain decision that needs a human, a look at the source, and a check on the maintainer’s track record. Never blindly install what AI proposes.

Reproducibility and Offline Mirrors

There is no native requirements.lock in Ansible, so we build the equivalent by hand. Pin every version (including transitives) and, for air-gapped or compliance environments, mirror artifacts so installs never reach out to the public internet at deploy time.

For collections, a private Automation Hub or a plain ansible-galaxy collection download cache works well:

# Download pinned collections into a local directory for an offline mirror
ansible-galaxy collection download -r requirements.yml -p ./offline_collections

# Later, on the air-gapped host, install only from that local source
ansible-galaxy collection install -r requirements.yml \
  --offline -p ./collections

Point your ansible.cfg at the mirror so nothing leaks back to galaxy.ansible.com:

# ansible.cfg
[galaxy]
server_list = "internal_hub"

[galaxy_server.internal_hub]
url = "https://hub.example.com/api/galaxy/content/published/"

AI can scaffold this configuration in seconds, but verify the URL paths and auth settings against your hub’s real API — those galaxy_server URLs are fiddly and version-specific, and a plausible-looking wrong path is exactly the kind of thing a language model produces. This is a good moment to route the change through an automated review on the code review dashboard before it lands.

Install Safely: Check-Mode and Least Privilege

Once your file is audited and pinned, the install itself should still be deliberate:

# Install exactly what is pinned, refusing to silently upgrade anything
ansible-galaxy install -r requirements.yml --force-with-deps

# Verify the playbook against the new versions WITHOUT changing hosts
ansible-playbook site.yml --check --diff

The --check --diff dry run is non-negotiable after any dependency change. A pinned-but-untested upgrade can still alter behavior — a new role default, a changed module argument — and check-mode surfaces that before it touches a real server. I think of the AI as a fast junior engineer: brilliant at the grunt work of auditing sixty entries, but its output is a pull request, not a deploy. A human reviews every change, and the dry run is the safety net under both of us.

And the hard rule that never bends: the AI never touches secrets. It does not get your Ansible Vault password, your Automation Hub token, or your git deploy keys. It audits the structure of your dependencies; it has no business near the credentials that authenticate them. If a workflow seems to require handing an assistant a vault key, the workflow is wrong.

Putting It Together

My current loop looks like this: every change to requirements.yml or a meta/main.yml runs through an AI audit prompt that flags unpinned, floating, or unquoted entries; I review the suggestions as a human, verify any version numbers against the real source, run ansible-playbook --check --diff, and only then merge. The supply-chain mindset — review every dependency, trust nothing by default — is the part the AI cannot do for me, and the part that matters most.

If you want a head start, the IaC category collects more of these workflows, and the prompt packs include a ready-to-run Ansible dependency-audit prompt. Pin your versions, dry-run your changes, keep the vault keys to yourself, and let AI do the boring auditing it is genuinely great at. The build that broke my Tuesday has not floated since.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.