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

UnitContainsInstall with
CollectionModules, plugins, roles and docs, versioned togetheransible-galaxy collection install
RoleTasks, handlers, templates and defaultsansible-galaxy role install
Standalone moduleA 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.nginx

Fully 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.builtin and 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.

Installing Ansible and setting up a control node Roles, Vault and idempotency

Last refreshed 2026-09-18.