Ansible Galaxy
Ansible Galaxy is the public registry of community roles, and ansible-galaxy role install pulls a role into your project the way pip pulls a package. The catch is that anyone can publish, so the real skill is vetting. A role with one star, last updated three years ago, and no tests is a liability you are installing directly into your deploy path. Pin versions and read the source before you trust someone else's role to configure your servers.
A good community role saves weeks — the standard nginx, PostgreSQL, and Docker roles are battle-tested across thousands of installs. An abandoned one costs more than writing your own, because you inherit its bugs and its assumptions and own them from the moment you adopt it.
ansible-galaxy role install
ansible-galaxy role install installs a named role into your roles path. The name carries a namespace — geerlingguy.nginx — where the prefix identifies the author and the suffix the role. By default it lands in ~/.ansible/roles, or in the project roles/ directory if you configure a roles_path. From there the role is callable by name, exactly like one you wrote yourself; once installed, Ansible does not distinguish a Galaxy role from a local one.
# pulls geerlingguy.nginx into the configured roles path $ ansible-galaxy role install geerlingguy.nginx
Run ad-hoc like this, the role installs on the one machine you ran it on — useful to try a role, wrong as the way your project records its dependencies. For that you want the install declared in a file every environment reads.
requirements.yml for Roles
Declare every external role and its version in requirements.yml, then run ansible-galaxy role install -r requirements.yml to install the whole set at once. This file is the reproducible record — the equivalent of a lockfile for your role dependencies. CI installs from it, the next engineer installs from it, and everyone resolves the identical roles. Without it, each laptop and each runner installs whatever happened to be latest the day it ran, and the playbook "works on my machine" for reasons nobody can reconstruct.
# requirements.yml roles: - name: geerlingguy.nginx version: "3.1.4" # a git tag, never floating HEAD - name: geerlingguy.postgresql version: "3.5.2"
Each role names a pinned version. Install from this file in CI and every environment gets the exact same code, every time, with the file itself serving as the reviewed, committed record of what your project depends on.
Vetting a Community Role
Before adopting a role, check recent commit activity, open-issue rot, test presence — Molecule or a CI pipeline — download count, and whether it supports your OS. A role with commits this month, few stale issues, real tests, and a million downloads is a different proposition from one that last moved in 2021 with twelve open issues and no tests. And vet the source, not just the badges: read the tasks for a hidden command: shelling out, or an assumption about your distribution that does not hold. You are putting this code in your deploy path; treat it like code you would review.
Pinning Versions
Install a specific git tag — version: "3.1.4" — never floating HEAD. A pinned version means a re-run installs identical code and an upstream change cannot silently alter your deploy. Leave it unpinned and a later install pulls whatever the author pushed since, so a deploy behaves differently with no commit on your side to explain it. Unpinned community roles are a supply-chain surprise waiting to happen — the surprise arrives on the day you can least afford it, in the middle of a deploy you did not change.
Roles Path and Layout
Installed roles land in the configured roles_path. Keep your own roles in the repo's roles/ directory, committed, and keep external ones declared in requirements.yml and installed in CI rather than vendored into the repo. That split keeps the boundary clean: the repo holds the roles you wrote and a manifest of the ones you borrowed, without checking in a copy of someone else's source that you can never cleanly update. The dependency is declared; the code is fetched fresh from the pinned tag each time.
- Installing a role without pinning a version, so a later
ansible-galaxy installpulls a changed upstream and a deploy behaves differently with no commit on your side to explain it. - Trusting a role by download count alone and skipping the source read, then shipping its hidden
command:task or its assumption about your OS straight into production. - Installing roles ad-hoc on each laptop instead of declaring them in
requirements.yml, so CI and the next engineer get a different set and the playbook "works on my machine." - Adopting an abandoned role — last commit 2021, twelve open issues — because it is the top search result, inheriting unpatched bugs you now own.
- Vendoring an external role's source into your repo and editing it, so you can never pull upstream fixes and have forked the role silently.
- Declare every external role with a pinned
version:inrequirements.ymland install from it in CI, so every environment resolves the identical role. - Vet before adopting: recent commits, low issue rot, present tests, your OS supported, real download numbers — and read the tasks for hidden
command:calls. - Keep your own roles in the repo's
roles/and external ones installed fromrequirements.yml, rather than vendoring third-party source you will never update. - Re-run
ansible-galaxy role install -r requirements.yml --forcedeliberately when bumping a pin, treating a role upgrade as a reviewed change, not a silent drift. - Prefer a maintained role with tests over rolling your own when one exists, but write your own before adopting an abandoned one whose bugs become yours.
version — the direct twin
Puppet Forge · Chef Supermarket the configuration-management siblings
Knowledge Check
Why pin a community role to a specific version in requirements.yml?
- A pinned tag means a re-run installs identical code, so an upstream change cannot silently alter your deploy
- Unpinned roles are rejected outright by the Galaxy resolver and refuse to install in any CI environment that lacks an explicit pin
- Pinning to an explicit version tag is the only way to make a role callable by name inside a play
- A version pin raises the role's precedence so it overrides any same-named local role on your path
What does requirements.yml give you that ad-hoc ansible-galaxy role install commands do not?
- A committed, reproducible record so CI and every engineer install the identical set of pinned roles
- Faster installs, because it fetches every role listed in the manifest concurrently across parallel worker threads
- Automatic upgrades to the latest published version of each role on every install run
- The ability to install roles fully offline, with no Galaxy or git network access
Which signal best indicates a community role is safe to adopt for production?
- Recent commits, low open-issue rot, present tests and your OS supported — confirmed by reading the tasks
- A high download count on Galaxy alone, since broad popularity reliably guarantees the role is correct for your platform
- Ranking as the top result in a Galaxy keyword search for that role's purpose
- A published version number above 1.0, which formally marks the role production-ready
Why is vendoring an external role's source into your repo and editing it a problem?
- You have silently forked it and can no longer pull upstream fixes, so future bugfixes never reach you
- Ansible refuses to load any role whose source directory has been copied to live inside the project repo itself
- Vendored roles lose their namespace prefix and become uncallable from any of your plays
- The role's
defaults/stop loading once the role is copied out of its original roles path
You got correct