ansible-documentation
ansible-documentation copied to clipboard
How to declare/handle external python dependencies in ansible collections/plugins
Summary
I am developing an ansible module in a collection that requires an external python dependency.
In my development context, that dependency is present, but when I try to execute the module on a target, it is not found.
So far, I encountered dependencies in actions, info modules or filters, that is in ansible plugins executing on the controller. Sometimes they are installed automatically, if not I just installed them manually on the controller. That's fine.
I assumed that Python dependencies required on the target would be packed into the Ansiballs, but from what I can see, that does not happen or if it does, it doesn't work in my case. Other than on the controller, having to install dependencies on target systems would imho not be acceptable.
I was trying to find any mention of this problem in the documentation, some best practices, even talked to bard and chatgpt and found nothing.
Then I tried to find examples for how others handle this, and in the limited time I invested for this search, I did not find any modules that use external dependencies. To me it looks like the reason for this is probably because modules evade using dependencies to avoid my current problem.
I think the documentation for developing modules should mention this, either telling authors to not use dependencies or how to do it correctly.
I'm new to both Python and Ansible, so there is a good chance that this is the reason why I hit the wall hard here, but since I read somewhere that roles should not be used to implement logic, a rookie trying to implement something in Python using external libraries should not be a fringe use case.
Meta: I probably chose the wrong issue type, but I don't find a better one.
Issue Type
Documentation Report
Component Name
lib/ansible
Ansible Version
$ ansible --version
ansible [core 2.15.5]
config file = /home/mu/share/projects/utech/ansible/ansible.cfg
configured module search path = ['/home/mu/share/projects/utech/ansible/library']
ansible python module location = /home/mu/.asdf/installs/python/3.11.6/lib/python3.11/site-packages/ansible
ansible collection location = /home/mu/share/projects/utech/ansible:/home/mu/share/projects/utech/ansible/{{ ANSIBLE_HOME }}/collections:/usr/share/ansible/collections
executable location = /home/mu/.asdf/installs/python/3.11.6/bin/ansible
python version = 3.11.6 (main, Oct 17 2023, 10:07:08) [GCC 11.4.0] (/home/mu/.asdf/installs/python/3.11.6/bin/python3.11)
jinja version = 3.1.2
libyaml = True
Configuration
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
COLLECTIONS_PATHS(/home/mu/share/projects/utech/ansible/ansible.cfg) = ['/home/mu/share/pr>
CONFIG_FILE() = /home/mu/share/projects/utech/ansible/ansible.cfg
DEFAULT_HOST_LIST(/home/mu/share/projects/utech/ansible/ansible.cfg) = ['/home/mu/share/pr>
DEFAULT_MODULE_PATH(/home/mu/share/projects/utech/ansible/ansible.cfg) = ['/home/mu/share/>
DEFAULT_ROLES_PATH(/home/mu/share/projects/utech/ansible/ansible.cfg) = ['/home/mu/share/p>
DEFAULT_STDOUT_CALLBACK(/home/mu/share/projects/utech/ansible/ansible.cfg) = yaml
DISPLAY_SKIPPED_HOSTS(/home/mu/share/projects/utech/ansible/ansible.cfg) = False
EDITOR(env: EDITOR) = vi
PERSISTENT_COMMAND_TIMEOUT(/home/mu/share/projects/utech/ansible/ansible.cfg) = 30
CALLBACK:
========
default:
_______
display_skipped_hosts(/home/mu/share/projects/utech/ansible/ansible.cfg) = False
OS / Environment
Ubuntu 22.04
Additional Information
Since the form insists on me adding information, this is what I think is related:
Ansible has extensive documentation, but it's incredibly hard and an overall rather frustrating experience to develop any kind of reusable components. This starts with the terminology (everything seems to be a plugin. Actions are plugins executed on the controller, modules are plugins executed on the host - confusing), continues with the fact that each artefact type has it's own and often completely difference interface with ansible (argument parsing/spec), there is a lot of redundancy, it's unclear which mechanism is best for some use case, and I have no idea what the implications of making this or that choice would be.
I often have use cases that seem to be rather natural and if I try to implement them I encounter road blocks all around me and when I search on google, I don't find anything, as if I'm the only person having this particular problem.
In this particular case, I have the choice to find out how to handle dependencies or to copy&paste the content of an external module (and its recursive dependencies if any) into a module_utils folder. I really don't want to do this (first because it's ugly, second because I don't want to take ownership over the code). Can I be the first user having this problem? I feel really stupid here.
Code of Conduct
- [X] I agree to follow the Ansible Code of Conduct