Why Collections Changed Everything
When Ansible 2.10 split the monolithic package into collections, it was the biggest architectural shift in Ansibleβs history. Suddenly, content was modular, versioned, and independently maintainable. But two years later, most teams are still writing collections that nobody reuses.
Iβve built and published over 20 collections on Ansible Galaxy and maintained content across Ansible Pilot β hereβs what actually works.
Collection Structure That Scales
my_company.platform/
βββ galaxy.yml
βββ README.md
βββ CHANGELOG.md
βββ meta/
β βββ runtime.yml
βββ plugins/
β βββ modules/
β βββ module_utils/
β βββ filter/
β βββ lookup/
βββ roles/
β βββ common/
β βββ deploy/
βββ playbooks/
βββ tests/
β βββ integration/
β βββ unit/
βββ docs/The key insight: treat collections as products, not dumping grounds. Each collection should have a clear scope β one domain, one team, one purpose.
Naming Conventions That Prevent Chaos
# galaxy.yml
namespace: acme_corp
name: cloud_platform
version: 2.1.0
description: Cloud infrastructure provisioning for ACME Corp
authors:
- Platform Engineering Team
dependencies:
amazon.aws: ">=6.0.0"
community.general: ">=7.0.0"Follow these rules:
- Namespace: company or team name (lowercase, underscores)
- Collection name: domain-specific (not
utilsorcommon) - Semantic versioning: breaking changes = major bump, always
Testing Collections Properly
Most collection testing I see is nonexistent. Hereβs the minimum viable testing setup with Molecule:
# molecule/default/molecule.yml
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: rhel9
image: registry.access.redhat.com/ubi9/ubi
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible# molecule/default/converge.yml
- name: Converge
hosts: all
collections:
- acme_corp.cloud_platform
roles:
- role: acme_corp.cloud_platform.deploy
vars:
deploy_env: staging
deploy_version: "1.2.3"Integration tests should cover:
- Idempotency: run twice, second run shows zero changes
- Check mode:
--checkproduces accurate diff - Error handling: invalid inputs fail gracefully with clear messages
For deeper testing patterns, check my Ansible by Example guides β I cover Molecule testing extensively there.
Versioning and Changelog Strategy
# Use antsibull-changelog for consistent changelogs
pip install antsibull-changelog
antsibull-changelog init
antsibull-changelog release --version 2.1.0# changelogs/fragments/add-rds-module.yml
minor_changes:
- rds_instance - add support for Aurora Serverless v2 provisioning
bugfixes:
- ec2_security_group - fix idempotency when rules contain IPv6 CIDR blocksPublishing to Galaxy and Private Automation Hub
# Build the collection artifact
ansible-galaxy collection build
# Publish to Galaxy
ansible-galaxy collection publish acme_corp-cloud_platform-2.1.0.tar.gz --api-key $GALAXY_API_KEY
# Or publish to Private Automation Hub
ansible-galaxy collection publish acme_corp-cloud_platform-2.1.0.tar.gz --server https://hub.internal.acme.com/api/galaxy/For enterprise teams using Red Hat Ansible Automation Platform, Private Automation Hub is the way to go β it gives you curated, approved content without exposing anything to the public internet.
Cross-Collection Dependencies Done Right
# galaxy.yml β pin to ranges, not exact versions
dependencies:
ansible.netcommon: ">=5.0.0,<7.0.0"
ansible.utils: ">=2.0.0"Never pin exact versions unless you have a specific compatibility issue. Range pins let downstream users resolve conflicts.
CI/CD Pipeline for Collections
# .gitlab-ci.yml
stages:
- lint
- test
- publish
lint:
image: python:3.11
script:
- pip install ansible-lint
- ansible-lint
test:
image: quay.io/ansible/creator-ee:latest
script:
- ansible-test sanity --color
- ansible-test units --color
- ansible-test integration --color
publish:
stage: publish
only:
- tags
script:
- ansible-galaxy collection build
- ansible-galaxy collection publish *.tar.gz --api-key $GALAXY_TOKENI walk through this entire CI pipeline setup in my Terraform Pilot infrastructure-as-code guides, where the same GitLab CI patterns apply.
What Iβve Learned After 772+ Tutorials
After creating over 772 Ansible tutorials on Ansible Pilot, here are the patterns that separate good collections from great ones:
- Documentation is not optional β every module needs examples that copy-paste and work
- Defaults should be sane β a role with zero vars should do something useful
- Idempotency is non-negotiable β if itβs not idempotent, itβs a script, not automation
- Test on multiple platforms β RHEL, Ubuntu, and at minimum one more
- Keep changelogs human-readable β βfixed stuffβ is not a changelog entry
Next Steps
If youβre starting your collections journey, begin with the Ansible by Example book series for foundational patterns, then graduate to building your own reusable content. The investment in proper collection architecture pays dividends every time a teammate reuses your work instead of reinventing it.
