11

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: git@github.com: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
SpongeBobPHPants
  • 641
  • 7
  • 19
  • 2
    From what I gather in the doc, you should fully qualify your roles: `mynamespace.mycollection.role1`. This is noted around the end of this documentation section: https://docs.ansible.com/ansible/latest/dev_guide/migrating_roles.html#comparing-standalone-roles-to-collection-roles – β.εηοιτ.βε Nov 14 '20 at 18:21
  • 1
    Thanks. I totally agree that's what the docs say. I have tried that. I'll edit the question to clarify (I think I alluded to it already). – SpongeBobPHPants Nov 14 '20 at 20:19

2 Answers2

5

I 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.

SpongeBobPHPants
  • 641
  • 7
  • 19
  • Your answer seems to add more confusion for others who want to start working with collections. From what I know you should be using Fully Qualified Collection Names (FQCN) hence not `mynamespace.my_role1` but instead `mynamespace.my_collection.my_role1`. Be consistent. (https://en.wikipedia.org/wiki/Principle_of_least_astonishment) Since you mention Jeff Geerling, he has his own opinion: https://www.jeffgeerling.com/blog/2020/ansible-best-practices-using-project-local-collections-and-roles – Benjamin Jan 30 '23 at 05:29
-5

ansible playbook, was formerly known as converge. Try converting your workspace to yml file format for read only data structure.

greet
  • 1
  • 1