What is an Ansible collection, how does it relate to roles, and what does a fully qualified name such as community.general.timezone refer to?
answer
- engine and content ship separately now
- namespace dot collection dot thing
- packaging unit, not an organising unit
- roles can live inside one
- short names resolve through a search path
basics
~20 sA collection is Ansible's packaging and distribution unit: a namespace.name bundle of modules, plugins, roles and playbooks. Content inside it is addressed by fully qualified collection name, such as community.general.timezone, and installed with ansible-galaxy collection install.
solid answer
~40 sSince the 2.10 split, `ansible-core` ships only a small built-in set of modules and everything else lives in collections. A collection is a versioned package identified by `namespace.name` - `community.general`, `amazon.aws`, `ansible.posix` - containing `plugins/modules`, other plugin types, `roles/` and `playbooks/`, described by a `galaxy.yml`. Content is referenced by its fully qualified collection name: `community.general.timezone` means the `timezone` module in the `community.general` collection, and `ansible.builtin.copy` is the core `copy` module. Roles and collections are not competitors - a collection is the shipping container and a role can be one of the things inside it, referenced as `namespace.name.rolename`. You install collections with `ansible-galaxy collection install`, usually from a pinned `requirements.yml`. Writing FQCNs everywhere is now standard practice because short names resolve through a search path and can silently bind to the wrong module.
code
yaml · 10 lines# requirements.yml
collections:
- name: community.general
version: "8.6.1"
- name: amazon.aws
version: "7.5.0"
roles:
- src: geerlingguy.nginx
version: "3.1.4"go deeper
Be able to read an FQCN - namespace, collection, then the module or role name - and know that collections are installed with ansible-galaxy collection install rather than pip.
Explain the 2.10 split between ansible-core and content, what a collection contains, and that a collection is a distribution package that may itself ship roles addressed as namespace.collection.rolename.
Diagnose the module-not-found upgrade case, argue for FQCNs on determinism grounds, and say when you would publish content as a collection rather than a standalone role.
Decide where shared content lives for the organisation: namespaces you own, public Galaxy versus a private hub, and the release and versioning policy for internal collections consumed by many teams.
## Why collections exist Up to Ansible 2.9 the project shipped as one enormous repository: thousands of modules for every cloud, network vendor and database, all released on the engine's schedule. A fix to a single cloud module waited for the next Ansible release. The 2.10 split separated the **engine** (`ansible-core`) from the **content** (collections), so each collection versions and releases independently. The `ansible` package on PyPI is a curated bundle of `ansible-core` plus a large set of collections; installing `ansible-core` alone gives you only `ansible.builtin`. ## What is in a collection A collection is a directory tree with a `galaxy.yml` manifest and roughly this shape: ``` my_namespace/my_collection/ galaxy.yml plugins/ modules/ lookup/ filter/ roles/ playbooks/ docs/ ``` So it can carry modules, any plugin type, complete roles, and even playbooks. `ansible-galaxy collection init my_namespace.my_collection` scaffolds it, `ansible-galaxy collection build` produces a tarball, and `ansible-galaxy collection publish` pushes it to Galaxy or a private hub. ## Roles versus collections They answer different questions. A **role** is a unit of *organisation* inside your automation - a directory layout for one coherent piece of configuration. A **collection** is a unit of *distribution* - a versioned, namespaced package. The relationship is containment: a collection may ship zero, one or many roles, addressed as `namespace.collection.rolename`: ```yaml - hosts: web tasks: - name: Apply a role that ships inside a collection ansible.builtin.import_role: name: my_namespace.my_collection.webserver ``` Standalone roles installed from Galaxy still work - `ansible-galaxy role install geerlingguy.nginx` - and remain common. But new shared content, especially anything that includes custom modules or plugins, is published as a collection, because a collection can version its plugins alongside its roles while a standalone role's `library/` directory cannot be depended on cleanly. ## Fully qualified collection names An FQCN has three dot-separated parts: namespace, collection, content name. - `ansible.builtin.copy` - the `copy` module built into `ansible-core`. - `community.general.timezone` - the `timezone` module from `community.general`. - `amazon.aws.ec2_instance` - the EC2 instance module from `amazon.aws`. Short names such as `copy:` still resolve, through a search path that prefers `ansible.builtin` and then any collections listed in the play's `collections:` keyword. The reason to write FQCNs anyway is determinism: a short name's meaning depends on what is installed and on the search order, so the same playbook can bind a different module on a different control node. Linting tools flag bare module names for exactly this reason, and FQCNs also make the dependency obvious to a reader - `amazon.aws.ec2_instance` tells you which collection must be installed, `ec2_instance` does not. ## Installing and declaring ```yaml # requirements.yml collections: - name: community.general version: "8.6.1" - name: amazon.aws version: "7.5.0" roles: - src: geerlingguy.nginx version: "3.1.4" ``` `ansible-galaxy collection install -r requirements.yml` installs the collections; `ansible-galaxy role install -r requirements.yml` installs the standalone roles. Collections resolve to a collections path (project-local with `-p`, otherwise a user or system path); roles resolve to `roles_path`. A collection may also declare its own dependencies on other collections in `galaxy.yml`, which `ansible-galaxy` resolves at install time. ## What interviewers are checking That you know the ecosystem you are working in is post-split: that a missing module is usually a missing *collection* rather than a broken Ansible, that `requirements.yml` is where dependencies are declared, and that FQCNs are not verbosity for its own sake. A candidate who still describes Ansible as "one big install with every module" is describing 2.9.
- A playbook that worked on Ansible 2.9 now fails with a module-not-found error. What is the likely cause?The module moved into a collection during the 2.10 split and the control node has only `ansible-core`, or the curated bundle installed does not include it. Find the owning collection, add it to `requirements.yml` with a pinned version, install it with `ansible-galaxy collection install -r`, and switch the task to the fully qualified name so the dependency is visible in the code.
- Why write ansible.builtin.copy rather than just copy?Short names resolve through a search path that depends on what is installed and on the play's `collections:` keyword, so the same task can bind a different module on a different control node. The FQCN removes that ambiguity and documents which collection a reader needs installed. Linters flag bare module names for this reason.
- When would you publish a collection instead of a standalone Galaxy role?Whenever the content includes custom modules, filters or lookups, or when several roles share code and should be versioned together. A collection versions plugins and roles as one artifact with a namespace, which a standalone role's `library/` directory cannot do cleanly. A single self-contained role with no plugins is still fine to publish on its own.
saying these in an interview costs you the question
- Says collections replaced roles entirely
- Thinks every module still ships with ansible-core
- Cannot parse namespace.collection.content in an FQCN
- Installs collections with pip install
- Treats FQCNs as optional verbosity with no benefit