Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible playbook which uses a role defined in a collection

This is an example of an Ansible playbook I am currently playing around with:

---
- hosts: all

  collections:
    - mynamespace.my_collection

  roles:
    - mynamespace.my_role1
    - mynamespace.my_role2
    - geerlingguy.repo-remi

The mynamespace.my_collection collection is a custom collection that contains a couple of roles, namely mynamespace.my_role1 and mynamespace.my_role2.

I have a requirements.yml file as follows:

---
collections:
  - name: [email protected]:mynamespace/my_collection.git

roles:
  - name: geerlingguy.repo-remi
    version: "2.0.1"

And I install the collection and roles as follows:

ansible-galaxy collection install -r /home/ansible/requirements.yml --force
ansible-galaxy role install -r /home/ansible/requirements.yml --force

Each time I attempt to run the playbook it fails with the following error:

ERROR! the role 'mynamespace.my_role1' was not found in mynamespace.my_collection:ansible.legacy:/home/ansible/roles:/home/ansible_roles:/home/ansible

The error appears to be in '/home/ansible/play.yml': line 42, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  roles:
    - mynamespace.my_role1
      ^ here

For the avoidance of doubt, I have tried multiple ways of defining the roles in the playbook including mynamespace.my_collection.my_role1 (the fully qualified name of the role within the collection).

I suspect I've done something wrong or misunderstood how it should work but my understanding is a collection can contain multiple roles and once that collection is installed, I should be able to call upon one or more of the roles within the collection inside my playbook to use it but it doesn't seem to be working for me.

The error seems to suggest it is looking for the role inside the collection but not finding it.

The collection is installed to the path /home/ansible_collections/mynamespace/my_collection and within that directory is roles/my_role1 and roles/my_role2.

Maybe the structure of the roles inside the collection is wrong?

I'm using Ansible 2.10 on CentOS 8.

Thanks for any advice!

EDIT:

I just wanted to expand on something I alluded to earlier. I believe the docs say the fully qualified name should be used to reference the role in the collection within the playbook.

Unfortunately, this errors too:

ERROR! the role 'mynamespace.my_collection.my_role1' was not found in mynamespace.my_collection:ansible.legacy:/home/ansible/roles:/home/ansible_roles:/home/ansible

The error appears to be in '/home/ansible/play.yml': line 42, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  roles:
    - mynamespace.my_collection.my_role1
      ^ here
like image 960
SpongeBobPHPants Avatar asked Nov 14 '20 17:11

SpongeBobPHPants


People also ask

How do you define a role in Ansible playbook?

Roles provide a framework for fully independent, or interdependent collections of variables, tasks, files, templates, and modules. In Ansible, the role is the primary mechanism for breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse.

What is the difference between an Ansible role and a playbook?

Ansible playbook is a script file which contains all the tasks that need to be performed along with all the ingredients required to perform these tasks. Roles are ways of automatically certain var files, tasks, and handlers based on the known file structure.

How do you add roles in Ansible playbook?

In Ansible 1.4 and later you can configure a roles_path to search for roles. Use this to check all of your common roles out to one location, and share them easily between multiple playbook projects. See Configuration file for details about how to set this up in ansible. cfg.

What is the difference between collection and playbook in Ansible?

Roles defined inside a collection always implicitly search their own collection first, so you don’t need to use the collections keyword to access modules, actions, or other roles contained in the same collection. In a playbook, you can control the collections Ansible searches for modules and action plugins to execute.

How do I use collections in Ansible roles?

Within a role, you can control which collections Ansible searches for the tasks inside the role using the collections keyword in the role’s meta/main.yml. Ansible will use the collections list defined inside the role even if the playbook that calls the role defines different collections in a separate collections keyword entry.

What is the use of a group in Ansible?

Group web or database can then be used in playbooks or roles to specify the hosts to apply. The groups can also be used in command ansible to run ad-hoc commands. Show activity on this post. Also keep in mind a playbook can call more than one role if a meta file is used that is intended to affect the different roles.

What is Ansible-Galaxy?

Ansible Galaxy is a free site for finding, downloading, rating, and reviewing all kinds of community-developed Ansible roles and can be a great way to get a jumpstart on your automation projects. The client ansible-galaxy is included in Ansible.


1 Answers

I posted this as an issue over at the ansible/ansible repo and we did get to the bottom of this.

One small clue missing is the contents of my /etc/ansible/ansible.cfg file:

COLLECTIONS_PATHS(/etc/ansible/ansible.cfg) = ['/home/ansible_collections']
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = ['/home/ansible_roles']

To quote contributor Sloane Hertel directly:

There's a bug/discrepancy between how ansible-galaxy and ansible handle the collections path. ansible-galaxy tries to be smart and adds ansible_collections to the path if it's not there already, but ansible always joins ansible_collections to the path - the playbook is trying to find the collection in /home/ansible_collections/ansible_collections/.

The solution, therefore, is to change my COLLECTIONS_PATHS value from /home/ansible_collections to /home.

From then on ansible-playbook will be searching for any roles in collections in the path /home/ansible_collections/mynamespace/roles instead of /home/ansible_collections/ansible_collections/mynamespace/roles.

I changed my directory structure slightly:

home/
├─ ansible_collections/
│  ├─ mynamespace/
│  │  ├─ my_collection/
│  │  │  ├─ roles/
│  │  │  │  ├─ mynamespace
│  │  │  │  │  ├─ my_role1/
│  │  │  │  │  │  ├─ meta/
│  │  │  │  │  │  ├─ tasks/

Which now means my playbook file looks like:

---
- hosts: all

  collections:
    - mynamespace.my_collection

  roles:
    - mynamespace.my_role1
    - mynamespace.my_role2
    - geerlingguy.repo-remi

And the roles are now found correctly.

like image 85
SpongeBobPHPants Avatar answered Sep 20 '22 02:09

SpongeBobPHPants