A role is one bundle of automation (tasks + handlers + templates). A collection is a versioned tarball that bundles many roles, modules, plugins, and docs together under a namespace.
| Role | Collection | |
|---|---|---|
| Contains | tasks, handlers, vars, templates | roles + modules + plugins + docs |
| Naming | geerlingguy.mysql | community.mysql |
| Distribution | git repo via Galaxy | versioned tarball via Galaxy or Hub |
| Modules? | Custom modules in library/ | First-class — that's the main use case |
Since Ansible 2.10, every module ideally lives inside a collection. The full name is
namespace.collection.module — for example, the copy module is
ansible.builtin.copy, and the MySQL DB module is community.mysql.mysql_db.
---
- hosts: databases
tasks:
# FQCN — preferred for ALL modules (clearer, future-proof)
- name: Install MySQL
ansible.builtin.dnf:
name: mysql-server
state: present
- name: Create database
community.mysql.mysql_db:
name: myapp
state: present
- name: Open firewall
ansible.posix.firewalld:
port: 3306/tcp
state: enabled
# Short form still works for ansible.builtin (deprecated for community.*)
- name: Render config
template: # ← same as ansible.builtin.template
src: my.cnf.j2
dest: /etc/my.cnf
ansible-lint warns on bare module names from non-builtin collections. New code should always use FQCN. The lint rule is fqcn[action]; you can suppress per-task with a noqa comment but better to just spell it out.# Install latest version of a single collection
ansible-galaxy collection install community.mysql
# A specific version
ansible-galaxy collection install community.mysql:3.10.0
# Into a project-local path
ansible-galaxy collection install community.mysql -p ./collections
# List installed collections
ansible-galaxy collection list
# Update one
ansible-galaxy collection install community.mysql --upgrade
The same requirements.yml can pin both roles and collections — they go in
separate top-level keys:
---
collections:
- name: community.mysql
version: ">=3.10.0,<4.0.0" # version range, not exact pin
- name: community.postgresql
version: 3.6.0
- name: ansible.posix
version: 1.5.4
- name: community.general
# private from a git repo
- name: company.platform
source: git+https://gitlab.example.com/platform/ansible-collection.git
version: v0.4.0
roles:
- name: geerlingguy.docker
version: 7.4.0
# Installs both collections AND roles in one command
ansible-galaxy install -r requirements.yml
# To install ONLY collections:
ansible-galaxy collection install -r requirements.yml -p ./collections
# To install ONLY roles:
ansible-galaxy role install -r requirements.yml -p ./roles
| Collection | What it gives you |
|---|---|
community.mysql | mysql_db, mysql_user, mysql_query, mysql_replication, mysql_variables, mysql_info |
community.postgresql | 30+ modules covering DBs, users, schemas, extensions, replication, pg_hba, tablespaces |
community.mongodb | Replica sets, sharded clusters, users, indexes, balancer state |
community.general | The catch-all — archive, ini_file, cron, htpasswd, hundreds more |
ansible.posix | firewalld, mount, sysctl, selinux, authorized_key |
community.crypto | OpenSSL keys, certs, CSRs, x509 manipulation |
Collections are the right unit when you want to ship multiple related roles + custom modules together. Skeleton with one command:
# Create a collection skeleton
ansible-galaxy collection init company.platform
cd company/platform
# Layout
ls -la
# galaxy.yml ← collection metadata (name, version, deps)
# README.md
# docs/
# meta/
# plugins/
# modules/ ← custom modules go here
# filter/ ← custom filters
# lookup/
# roles/ ← roles bundled with the collection
# common/
# mysql/
# proxysql/
# playbooks/ ← optional bundled playbooks
---
namespace: company
name: platform
version: 1.0.0
readme: README.md
authors:
- Platform Team <platform@example.com>
description: Internal platform automation collection
license:
- MIT
tags:
- infrastructure
- mysql
- proxysql
dependencies:
community.mysql: ">=3.10.0"
ansible.posix: ">=1.5.0"
repository: https://gitlab.example.com/platform/ansible-collection-platform
# Build a tarball
ansible-galaxy collection build
# → company-platform-1.0.0.tar.gz
# Publish to a hub
ansible-galaxy collection publish \
company-platform-1.0.0.tar.gz \
--server my_hub \
--token $MY_HUB_TOKEN
# Or distribute via git — others install with:
# ansible-galaxy collection install \
# git+https://gitlab.example.com/platform/ansible-collection-platform.git,v1.0.0
community.mysql collection is a good shape to imitate: many MySQL modules + a couple of MySQL roles + reusable filters, all versioned together.