"community.kubernetes.k8s" can't be resolved in Ansible even if the collection is installed

7/2/2021

I want to create some Kubernetes objects using Ansible. The community.kubernetes.k8s can do this, which is included in the community.kubernetes collection. When I try to create a namespace

- name: Create ns
  community.kubernetes.k8s:
    api_version: v1
    kind: Namespace
    name: myapp
    state: present

Ansible throws an error that the collection is not installed:

ERROR! couldn't resolve module/action 'community.kubernetes.k8s'. This often indicates a misspelling, missing collection, or incorrect module path.

The error appears to be in '/home/user/ansible-project/ansible/roles/k8s/tasks/main.yml': line 14, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


- name: Create ns
  ^ here

But it is allready installed, as ansible-galaxy collection install confirms:

$ ansible-galaxy collection install community.kubernetes
Process install dependency map
Starting collection install process
Skipping 'community.kubernetes' as it is already installed

My installed Ansible version is 2.9.6 on Python 3.8.10, where ansible_python_interpreter=/usr/bin/python3 is set and Python2 not installed on the workstation (targeted with ansible_connection=local).

What am I doing wrong?

What I've already tried

Using old + new namings

Ansible 2.9+ is required to install collections with ansible-galaxy, so this should work. In the collection documentation I found this notice:

IMPORTANT The community.kubernetes collection is being renamed to kubernetes.core. As of version 2.0.0, the collection has been replaced by deprecated redirects for all content to kubernetes.core. If you are using FQCNs starting with community.kubernetes, please update them to kubernetes.core.

Altough this seems confusing since the Ansible documentation still refers to community.kubernetes.k8s I tried this too

- name: Create ns
  kubernetes.core.k8s:
  # ...

And to be sure

$ ansible-galaxy collection install kubernetes.core
Process install dependency map
Starting collection install process
Skipping 'kubernetes.core' as it is already installed

But still throwing the same couldn't resolve module/action 'kubernetes.core.k8s' error. Both directories ~/.ansible/collections/ansible_collections/kubernetes/core/ and ~/.ansible/collections/ansible_collections/community/kubernetes/ exists, so I'd guess that both (old + new naming) should work.

Checking the directory

By calling ansible-galaxy with -vvv switch, I proved that /home/user/.ansible/collections/ansible_collections is used. It also shows that those packages installs two packages under the hood: The old community.kubernetes and the new kubernetes.core:

Installing 'community.kubernetes:2.0.0' to '/home/user/.ansible/collections/ansible_collections/community/kubernetes'
Downloading https://galaxy.ansible.com/download/community-kubernetes-2.0.0.tar.gz to /home/user/.ansible/tmp/ansible-local-1610573465r9kd/tmpz_hw9gza
Installing 'kubernetes.core:2.1.1' to '/home/user/.ansible/collections/ansible_collections/kubernetes/core'
Downloading https://galaxy.ansible.com/download/kubernetes-core-2.1.1.tar.gz to /home/user/.ansible/tmp/ansible-local-1610573465r9kd/tmpz_hw9gza

which seems even more confusing to me, since the old repo says

This repo hosts the community.kubernetes (a.k.a. kubernetes.core) Ansible Collection.

For me this sounds like they're just changing the name. But as we can see, kubernetes.core has its own repo and version (2.1.1 vs 2.0).

To make sure that this directory is used, I added the following to my local ansible.cfg at project scope:

[defaults]
collections_paths = /home/user/.ansible/collections/ansible_collections/

Doesn't made any difference.

-- Lion
ansible
ansible-collections
ansible-galaxy
kubernetes

1 Answer

7/2/2021

Found out that specifying collections_paths works, but without ansible_collections. Ansible expects the collections directory:

collections_paths = /home/user/.ansible/collections/

It's also nice that using ~ as placeholder for the current users home directory works, so we can keep it independent from the current user like this:

collections_paths = ~/.ansible/collections/

Now my playbook runs fine and the namespace is created:

$ kgns | grep myapp
myapp           Active   9m42s

Alternatively

It's also possible to install them globally on the entire system by specifying as target directory (-p switch) to ansible-galaxy:

sudo ansible-galaxy collection install -r requirements.yml -p /usr/share/ansible/collections

Where requirements.txt contains (for testing purpose both, see next section)

collections:
  - community.kubernetes
  - kubernetes.core

But as long as there are no good reasons to install packages globally, I'd keep them locally - so imho specifying collections_paths to the local user in ansible.cfg seems the preferable solution - we also avoid executing ansible-galaxy with root permissions this way.

Which package to use now?

For testing purpose, I installed both to isolate the issue of my error. Since community.kubernetes is deprecated, I'd prefer kubernetes.core. This means to change the requirements file to

collections:
  - name: kubernetes.core

or use ansible-galaxy collection install kubernetes.core alternatively - but I'd recommend using a requirements.yml which keeps your requirements well documented and makes it easier for others to install them (especially if there are more than one).

In your playbooks/roles, you just have to use kubernetes.core.* instead of community.kubernetes.*. From my first point of view, it seems that not much has changed yet - it still makes sense to follow the new documentation for kubernetes.core.* to avoid issues caused by using an outdated documentation.

-- Lion
Source: StackOverflow