ansible-lint
ansible-lint copied to clipboard
"couldn't resolve module/action" for local module used in role
I have an Ansible playbook laid out as follows:
./
├── hosts
├── library/
│ └── nop.py
├── playbook.yml
└── roles/
└── myrole/
└── tasks/
└── main.yml
Contents of library/nop.py:
#!/usr/bin/python3
from ansible.module_utils.basic import AnsibleModule
DOCUMENTATION = r"""
---
module: nop
short_description: Does nothing
options:
"""
def run_module():
module = AnsibleModule(argument_spec={}, supports_check_mode=True)
module.exit_json(changed=False)
def main():
run_module()
if __name__ == "__main__":
main()
Contents of playbook.yml:
---
- name: Play
hosts: all
roles:
- myrole
Contents of roles/myrole/tasks/main.yml:
---
- name: Do nothing
nop:
Running ansible-lint on this directory gives the error:
WARNING Listing 1 violation(s) that are fatal
syntax-check[specific]: couldn't resolve module/action 'nop'. This often indicates a misspelling, missing collection, or incorrect module path.
roles/myrole/tasks/main.yml:2:3
Rule Violation Summary
count tag profile rule associated tags
1 syntax-check[specific] min core, unskippable
Failed: 1 failure(s), 0 warning(s) on 5 files.
However, if the nop module is invoked as a task directly in playbook.yml instead, ansible-lint is fine with it.
OS / ENVIRONMENT
ansible-lint 6.20.3 using ansible-core:2.15.5 ansible-compat:4.1.10 ruamel-yaml:0.17.35 ruamel-yaml-clib:0.2.8
- ansible installation method: pip
- ansible-lint installation method: pip
My understanding is that the reason this works when using ansible-playbook is that when it loads the playbook file, the "adjacent" library and collections/ansible_collections directories are added implicitly relative to the location of the playbook file. Then when the playbook loads a role, those directories are already in the search paths, so the role is able to use the custom modules (and other plugins).
But when you run ansible-lint (with no parameters) such that it heuristically scans all the files in the current directory, it seems to sometimes - but not always? - load roles without first loading a playbook, meaning that the playbook-adjacent directories may or may not have been added to ansible's search paths.
I've been finding this behaviour to be inconsistent/unpredictable. For example, in my production ansible playbooks, I currently have two different roles that both use a custom module from my toplevel library directory. Right now ansible-lint is giving me this error on one of the roles but not the other - I've been pulling my hair out a bit on this since it's the same module in both roles, and I can't figure out why one gives an error when the other doesn't.
anyone got simple workaround?
I am running into the same error, however, only whilst using ansible-lint@main as a GitHub workflow action. Running ansible-lint locally did not fail, yet.
The used version locally is:
❯ ansible-lint --version
ansible-lint 6.22.1 using ansible-core:2.16.2 ansible-compat:4.1.10 ruamel-yaml:0.17.40 ruamel-yaml-clib:0.2.7
Edit:
Maybe my issue is not related. Adding the module/collection in requirements.yml solved the issue.
I see this error when importing a role into the Ansible Galaxy. The importer ignores this problem.
https://galaxy.ansible.com/ui/standalone/roles/vbotka/ansible_lint/import_log/
===== LOADING ROLE =====
Importing with galaxy-importer 0.4.19
Determined role name to be ansible_lint
Linting role ansible_lint via ansible-lint...
ansible-lint/tasks/packages.yml:9:7: syntax-check[specific]: couldn't resolve module/action 'community.general.pkgng'. This often indicates a misspelling, missing collection, or incorrect module path.
...ansible-lint run complete
Legacy role loading complete
I see this problem on all my roles that use any collection. For example,
https://galaxy.ansible.com/ui/standalone/roles/vbotka/linux_postinstall/import_log/
Other "heavy-duty" roles suffer from this too. For example,
https://galaxy.ansible.com/ui/standalone/roles/mrlesmithjr/netplan/import_log/
I am running into the same error, however, only whilst using
ansible-lint@mainas a GitHub workflow action. Runningansible-lintlocally did not fail, yet.The used version locally is:
❯ ansible-lint --version ansible-lint 6.22.1 using ansible-core:2.16.2 ansible-compat:4.1.10 ruamel-yaml:0.17.40 ruamel-yaml-clib:0.2.7Edit:
Maybe my issue is not related. Adding the module/collection in
requirements.ymlsolved the issue.
Worked for me adding requirements.yml in the root folder.
[!NOTE]
For some reason it does not work withrequirements.yaml. Seems like is not supported in the documentation.
requirements.yml in the root folder does not help
shell> cat requirements.yml
---
collections:
- name: community.general
source: https://galaxy.ansible.com
Galaxy reports the same error:
===== LOADING ROLE =====
Importing with galaxy-importer 0.4.20
Determined role name to be ansible_lint
Linting role ansible_lint via ansible-lint...
ansible-lint/tasks/packages.yml:9:7: syntax-check[specific]: couldn't resolve module/action 'community.general.pkgng'. This often indicates a misspelling, missing collection, or incorrect module path.
...ansible-lint run complete
Legacy role loading complete
See: https://galaxy.ansible.com/ui/standalone/roles/vbotka/ansible_lint/import_log/
A workaround which addresses the related issue described in #4042 (closed as duplicate of this issue) is to set the ANSIBLE_LIBRARY environment variable appropriately.
For example, given a role laid out like this:
.
├── defaults
│ └── main.yml
├── library
│ └── mongodb_replicaset_members.py
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
└── vars
└── main.yml
Running ansible-lint in the top directory fails with:
syntax-check[unknown-module]: couldn't resolve module/action 'mongodb_replicaset_members'. This often indicates a misspelling, missing collection, or incorrect module path.
However, running ANSIBLE_LIBRARY=library ansible-lint succeeds.
Tested with:
$ ansible-lint --version
ansible-lint 24.2.1 using ansible-core:2.16.5 ansible-compat:4.1.11 ruamel-yaml:0.18.6 ruamel-yaml-clib:0.2.8
Closing as this bug no longer happens with the code from main. Wait for the next release as I know one notable fix what merged but not released.