ansiblegitlabansible-2.xansible-collections

Create an ansible collection and use it on a playbook from gitlab


I created an ansible collection with 2 roles for deploy node_explorer and configure firewall. I'm on ansible 2.12

This is the root directory in the gitlab repository where it's stock (generate with ansible-creator)

.
└── mynamespace
    └── mycollection
        ├── CHANGELOG.rst
        ├── CODE_OF_CONDUCT.md
        ├── CONTRIBUTING
        ├── LICENSE
        ├── MAINTAINERS
        ├── README.md
        ├── changelogs
        │   └── config.yaml
        ├── devfile.yaml
        ├── docs
        │   └── docsite
        │       └── links.yml
        ├── extensions
        │   ├── eda
        │   │   └── rulebooks
        │   │       └── rulebook.yml
        │   └── molecule
        │       ├── integration_hello_world
        │       │   └── molecule.yml
        │       └── utils
        │           ├── playbooks
        │           │   ├── converge.yml
        │           │   └── noop.yml
        │           └── vars
        │               └── vars.yml
        ├── galaxy.yml
        ├── meta
        │   └── runtime.yml
        ├── plugins
        │   ├── README.md
        │   ├── action
        │   │   └── __init__.py
        │   ├── cache
        │   │   └── __init__.py
        │   ├── filter
        │   │   ├── __init__.py
        │   │   └── hello_world.py
        │   ├── inventory
        │   │   └── __init__.py
        │   ├── module_utils
        │   │   └── __init__.py
        │   ├── modules
        │   │   └── __init__.py
        │   ├── plugin_utils
        │   │   └── __init__.py
        │   ├── sub_plugins
        │   │   └── __init__.py
        │   └── test
        │       └── __init__.py
        ├── pyproject.toml
        ├── requirements.txt
        ├── roles
        │   ├── firewall
        │   │   ├── LICENSE
        │   │   ├── README.md
        │   │   ├── defaults
        │   │   │   └── main.yml
        │   │   ├── handlers
        │   │   ├── meta
        │   │   │   └── main.yml
        │   │   ├── molecule
        │   │   │   └── default
        │   │   │       ├── converge.yml
        │   │   │       └── molecule.yml
        │   │   ├── tasks
        │   │   │   └── main.yml
        │   │   └── templates
        │   ├── geerlingguy.node_exporter
        │   │   ├── LICENSE
        │   │   ├── README.md
        │   │   ├── defaults
        │   │   │   └── main.yml
        │   │   ├── handlers
        │   │   │   └── main.yml
        │   │   ├── meta
        │   │   │   └── main.yml
        │   │   ├── molecule
        │   │   │   └── default
        │   │   │       ├── converge.yml
        │   │   │       └── molecule.yml
        │   │   ├── tasks
        │   │   │   ├── config-version.yaml
        │   │   │   └── main.yml
        │   │   └── templates
        │   │       └── node_exporter.service.j2
        │   ├── run
        │   │   ├── README.md
        │   │   ├── defaults
        │   │   │   └── main.yml
        │   │   ├── files
        │   │   ├── handlers
        │   │   │   └── main.yml
        │   │   ├── meta
        │   │   │   └── main.yml
        │   │   ├── tasks
        │   │   │   └── main.yml
        │   │   ├── templates
        │   │   ├── tests
        │   │   │   └── inventory
        │   │   └── vars
        │   │       └── main.yml
        │   └── settings.json
        ├── test-requirements.txt
        ├── tests
        │   ├── integration
        │   │   ├── __init__.py
        │   │   ├── targets
        │   │   │   └── hello_world
        │   │   │       └── tasks
        │   │   │           └── main.yml
        │   │   └── test_integration.py
        │   └── unit
        │       ├── __init__.py
        │       └── test_basic.py
        └── tox-ansible.ini

Then I build it to generate the tar.gz package (from mynamepace/mycollection folder because there is an error at top level cause by no galaxy.yml file)

In another repository git, I have an ansible script and I want to import my collection above for use my two roles

From top folder of my ansible script, I have run Ansible install collection command

ansible-galaxy collection install <path to root folder of my collection>/mynamespace/mycollection/mynamespace-mycollection-1.0.0.tar.gz -p ./collections/

Then I configure my playbook for use it

    ---

- name: Installation de node exporter
  hosts: node_exporter
  tasks:
    - import_role:
        name: namespace.mycollection.geerlingguy.node_exporter
  tags:
    - node_exporter
  become: true

Then I run playbook

ansible-playbook node_exporter.yml -i inventories/transverse --vault-password-file ~/.vault_pass.txt

But My role is not found

ERROR! the role 'mynamespace.mycollection.geerlingguy.node_exporter' was not found in <ansible script root path>/roles:/home/myuser/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:<ansible script root path>

The error appears to be in '<ansible script root path>/node_exporter.yml': line 7, column 15, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    - import_role:
        name: mynamespace.mycollection.geerlingguy.node_exporter
              ^ here

I follow tutorial from https://blog.stephane-robert.info/docs/infra-as-code/gestion-de-configuration/ansible/collections/#build-de-notre-collection-ansible but I have failed. What's wrong with my actions ?

Other question, I need to script it in a gitlab pipeline, so i have to build and install collection froml gitlab on each pipeline. How Can I build/install a collection into a script ansible from gitlab ?

EDIT 1

I try to create ANSIBLE_COLLECTIONS_PATHS (also with ANSIBLE_COLLECTIONS_PATH) variable

export ANSIBLE_COLLECTIONS_PATHS=<path to root folder of my collection>/mynamespace/mycollection

And remove ID collection from import

---

- name: Installation de node exporter
  hosts: node_exporter
  tasks:
    - import_role:
        name: geerlingguy.node_exporter
  tags:
    - node_exporter
  become: true

But same error

ERROR! the role 'geerlingguy.node_exporter' was not found in <ansible script root path>/roles:/home/myuser/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:<ansible script root path>

The error appears to be in '<ansible script root path>/node_exporter.yml': line 7, column 15, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    - import_role:
        name: geerlingguy.node_exporter
              ^ her

EDIT 2

I have to build directy from root folder and indicate where is collection

ansible-galaxy collection build $PWD/mynamespace/mycollection

So, tar.gz is in the root folder and I have to indicate on installation to use a directory refer by ansible :

ansible-galaxy collection install <root folder of collection where is tar.gz>/mynamespace-mycollection-1.0.0.tar.gz --force -p ~/.ansible/roles

EDIT 3

So I try ty install directly with Git but namespace is nof ound

ansible-galaxy collection install -r requirements.yml --force -p ~/.ansible/roles -v

---
collections:
- name: https://myuser:mytokeng@mygitlaburl/ansible-collection.git
  type: git
  version: master

But I have this error

Process install dependency map
Cloning into '/home/myuser/.ansible/tmp/ansible-local-11314culy5a3n/tmp85qbomvb/ansible-collectionysty0mlw'...
remote: Enumerating objects: 136, done.
remote: Counting objects: 100% (136/136), done.
remote: Compressing objects: 100% (99/99), done.
remote: Total 136 (delta 12), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (136/136), 95.05 KiB | 2.02 MiB/s, done.
Resolving deltas: 100% (12/12), done.
Already on 'master'
Your branch is up to date with 'origin/master'.
ERROR! Neither the collection requirement entry key 'name', nor 'source' point to a concrete resolvable collection artifact. Also 'name' is not an FQCN. A valid collection name must be in the format <namespace>.<collection>. Please make sure that the namespace and the collection name contain characters from [a-zA-Z0-9_] only.

Tip: Make sure you are pointing to the right subdirectory — `/home/myuser/.ansible/tmp/ansible-local-11314culy5a3n/tmp85qbomvb/ansible-collectionysty0mlw` looks like a directory but it is neither a collection, nor a namespace dir.

Solution

  • This is a shot on the dark, I can't recreate your environment right now, but I think you need to remove the leading namespace.mycollection. from your import role.

    From this:

    tasks:
    - import_role:
        name: namespace.mycollection.geerlingguy.node_exporter
    

    To this:

    tasks:
    - import_role:
        name: geerlingguy.node_exporter
    

    I think this will still preference the geerlingguy namespace in your current namespace: Ansible should use the more specific (more local) role/collection before going to other sources.

    I believe this is discussed in the "Installing collections adjacent to playbooks" section of the documentation here:

    https://docs.ansible.com/ansible/latest/collections_guide/collections_installing.html

    As a final option, you might play with the ANSIBLE_COLLECTIONS_PATHS environment variable to tell available which collections it can use. This feels "bad" to me and probably will be more complex to maintain over time.