Collections, Galaxy and the module ecosystem
Collections versus roles, installing from a requirements file, FQCN module names, the ansible-galaxy commands, and evaluating a third-party role before you depend on it.
Collections and roles
| Unit | Contains | Install with |
|---|---|---|
| Collection | Modules, plugins, roles and docs, versioned together | ansible-galaxy collection install |
| Role | Tasks, handlers, templates and defaults | ansible-galaxy role install |
| Standalone module | A single file in library/ | Nothing, it is local |
# requirements.yml: pin everything you depend on
collections:
- name: ansible.posix
version: ">=1.5.4,<2.0.0"
- name: community.general
version: "==10.1.0"
- name: community.postgresql
version: "3.4.0"
- name: git+https://github.com/example/ansible-collection.git
type: git
version: v1.2.0
roles:
- name: geerlingguy.nginx
version: "3.1.4"
- src: https://github.com/example/ansible-role-app.git
scm: git
version: "1.0.0"ansible-galaxy collection install -r requirements.yml -p ./collections
ansible-galaxy collection list
ansible-galaxy collection verify ansible.posix
ansible-galaxy role install -r requirements.yml -p ./roles
ansible-galaxy role info geerlingguy.nginxFully qualified names
# avoid: relies on the module being found by a short name,
# which breaks when two collections both provide "user"
- name: Old style
user:
name: alice
# prefer: unambiguous, greppable and stable
- name: FQCN style
ansible.builtin.user:
name: alice
- name: Apache config from a collection
community.general.htpasswd:
path: /etc/nginx/.htpasswd
name: "{{ item.name }}"
password: "{{ item.password }}"
loop: "{{ htpasswd_users }}"
no_log: true- Short names only resolve for modules in
ansible.builtinand a default search path. Any ambiguity is a latent failure at runtime. - An FQCN tells a reader exactly which collection provides the module, which is what you need when a task misbehaves.
- Enable
ansible-lint's FQCN rule to enforce the style automatically rather than in review. - Redirects exist so a moved module keeps working, but they are a compatibility layer, not something to rely on for new code.
Evaluating a dependency
# 1. what does it actually do, and how is it maintained?
ansible-galaxy role info geerlingguy.nginx
# 2. read the tasks before trusting it with root
git clone --depth 1 --branch 3.1.4 https://github.com/geerlingguy/ansible-role-nginx /tmp/r
less -R /tmp/r/tasks/main.yml
grep -rn "shell:\|command:\|raw:" /tmp/r/tasks/
# 3. does it have tests and CI, and does it support your platform?
ls /tmp/r/molecule 2>/dev/null && cat /tmp/r/meta/main.yml
# 4. freeze the version you reviewed and record why
# a floating role is a change you did not review💡
A role from Galaxy runs as root on every host in your fleet. Read its tasks, check for
shell and command usage that bypasses idempotency, and confirm it declares the platforms you run. Vendoring your own thin role is often less work than adapting someone else's.FAQ
Should I use a community role or write my own?
Use a well-maintained role for a commodity service such as nginx or PostgreSQL. Write your own for anything specific to your application, where the role would need more overrides than the value it provides.
Why do I get a module not found error?
The collection is not installed, or it is installed into a path that is not in
collections_path. Check with ansible-galaxy collection list and prefer installing into a project-local directory.Related
Installing Ansible and setting up a control node Roles, Vault and idempotency
Last refreshed 2026-09-18.