3. Introduction to Ansible Collections

Ansible Collections are a standardized packaging format that bundle together multiple types of Ansible content—such as roles, modules, plugins, and documentation—into a single, organized unit. This approach streamlines the distribution and management of automation resources, allowing you to work with related content as a whole rather than handling individual roles or modules separately.

Collections greatly improve reusability and versioning. By packaging content into collections, you can easily share your work within your team or with the wider Ansible community. Collections also support structured version control, enabling you to track changes, update content safely, and ensure compatibility across projects. This makes maintaining and evolving automation simpler and more reliable.

Collections can be stored locally, published to public repositories like Ansible Galaxy, or hosted in private repositories (e.g., GitHub). This flexibility makes them suitable for both community-driven projects and enterprise environments where control and security are required. Overall, Ansible Collections provide a powerful way to organize, share, and manage automation content efficiently.

A key feature introduced by Ansible Collections is the namespace — the top-level identifier that groups collections, prevents naming conflicts, and indicates ownership. Examples include community.general or myorg.apache. Namespaces are particularly important in large organizations and when sharing collections publicly, as they help maintain clear boundaries and avoid collisions.

3.1 Collections vs Roles vs Modules

As discussed earlier, modules are the smallest building blocks in Ansible, performing atomic actions within tasks. Roles group tasks and related content into reusable units, sitting one level above modules. Collections extend this concept further by packaging roles, modules, plugins, and documentation together into a single, distributable format.

Collections sit at the top of the hierarchy as the primary packaging layer. They address challenges around sharing, versioning, and dependency management across projects—problems that roles alone cannot fully solve. Collections are therefore essential for maintaining consistency and scalability in larger automation environments.

3.2 Collection Structure

Like roles, collections are based on a strict directory structure. Ansible provides tooling to scaffold the initial directory layout.

The ansible-galaxy utility creates the directory structure for a collection. Unlike role creation, you must provide both a namespace and a collection name. For example, using myorg.unix (myorg as the namespace, unix as the collection name):

ansible-galaxy collection init myorg.unix

This command creates a full collection skeleton in the myorg/unix/ directory with the standard structure. Note the roles directory, which will contain all roles belonging to the collection.

myorg/
  unix/
    docs/
    plugins/
    roles/
    galaxy.yml
    README.md

3.3 Move Existing Role into the Collection

The previously created apache role can be moved into the collection under myorg/unix/roles/apache/. The role structure remains the same, and the tasks will continue to function without modification.

myorg/
  unix/
    roles/
      apache/
        tasks/
          main.yml
        defaults/
        handlers/
        meta/
        templates/
        vars/
        files/

3.4 Installing the Collection

In this tutorial, the collection is kept in the Ansible-aware collections/ansible_collections directory to make it directly available for playbooks. This works for special cases but is not suitable for regular enterprise usage. Before use, the collection should be installed to the proper location.

The installation location is configurable, but for now, we will use the default (~/.ansible). Ansible defines a standard way to bring a collection from any location into the local execution environment, supporting sources such as Galaxy, Git, URL, file directory, or subdirectories.

Typically, collection installation is managed via a requirements.yml file that specifies dependencies:

---
collections:
  - name: collections/ansible_collections/myorg/unix/
    type: dir
  - name: collections/ansible_collections/myorg/toolchain/
    type: dir
  - name: collections/ansible_collections/myorg/publicapi/
    type: git
    source: https://github.com/rstyczynski/ansible-collection-howto.git#/collections/ansible_collections/myorg/publicapi
    version: main
Note

Note that Ansible supports wide range of sources for collections, including Git, URL, file directory, or subdirectories. Collection stored at git may be placed in a subdirectory of the repository, what may be beneficial is some cases, however for production like collections always use dedicated repository, what gives full control over the collection to the owner.

With requirements.yml ready, install the dependencies using the ansible-galaxy tool:

ansible-galaxy install -r requirements.yml

You can verify that the collection is available:

ansible-galaxy collection list | grep myorg

3.5 Simplify the Playbook Using the Collection

With the role now inside the collection and the collection installed, you can reference it in your playbook:

- hosts: webservers
  become: yes

  roles:
    - myorg.unix.apache

Note the namespace prefix (myorg.unix). This allows you to use an apache role supplied by different authors, as collections use namespaces to avoid naming conflicts.

3.6 Benefits of Using Collections

Roles already provide organization and reusability, but collections extend these advantages significantly. A collection can bundle roles together with modules, plugins, and documentation in one package. You no longer need to manage these elements separately across projects.

While roles can be versioned (e.g., via Git tags or Galaxy releases), the mechanism is mostly ad hoc and external. Collections, by contrast, make versioning a first-class feature: every collection carries a version in its galaxy.yml, and dependencies on other collections can be declared in a structured way. This makes it easier to control upgrades, avoid incompatibilities, and ensure consistency across environments.

Another key benefit is unified distribution. While roles can be shared via Galaxy, GitHub, or private repositories, collections package multiple content types (roles, modules, plugins, documentation) together. This makes installation, versioning, and sharing more consistent and predictable, especially in larger environments.

In summary, collections are the natural next step after roles: they enhance reusability, standardize version control, and provide the dependency management needed for automation at scale.

3.7 Advanced Topics

3.7.1 Custom Collection Installation

Oracle distributes its OCI Collection through regular Ansible Galaxy servers, but this document focuses on local sources. The following example shows how to install the Oracle OCI Collection from a tar source, downloading and building it first:

curl -L -o /tmp/oci-ansible-collection-5.5.0.tar \
  https://github.com/oracle/oci-ansible-collection/archive/refs/tags/v5.5.0.tar.gz
mkdir -p /tmp/oci-ansible-collection-src
tar -xf /tmp/oci-ansible-collection-5.5.0.tar -C /tmp/oci-ansible-collection-src --strip-components=1
cd /tmp/oci-ansible-collection-src
ansible-galaxy collection build
ansible-galaxy collection install oracle-oci-5.5.0.tar.gz

ansible-galaxy collection list | grep oracle.oci

3.7.2 Blocking Public Galaxy Servers

Blocking public sources may not be straightforward without additional firewall measures. However, a simple technique disables public Galaxy servers at the Ansible level, which can be applied as a first protection layer in pipelines.

export ANSIBLE_GALAXY_SERVER_LIST=blocked
export ANSIBLE_GALAXY_SERVER_BLOCKED_TOKEN='blocked'

Now, if you try to install Oracle OCI:

ansible-galaxy collection install oracle.oci --force

Instead of installation progress, you will see an error:

[ERROR]: Required config 'url' for 'blocked' galaxy_server plugin not provided.