module_utils
#
- Directory:
./module_utils
- Documentation: https://docs.ansible.com/ansible/latest/dev_guide/developing_module_utilities.html
When writing extensions in Python, you can write all of the code in the extension file itself.
For instance, when writing a filter,
you can put all of the code in a file in the filter_plugins/
directory.
However, if you’re writing a large extension,
or even want to split up your extension into several Python files,
you can add files to module_utils
and import them.
Example #
That might look like this:
module_utils/example_lib.py
#
"""Example library
Imagine that it is documented here.
"""
def important_function_that_works_well(arg1):
"""I hope you tested this.
........... You didn't write any tests for this, did you. DID YOU.
"""
return f"{arg1} is my argument, wow what a useful function"
library/example_task.py
#
#!/usr/bin/env python
DOCUMENTATION = """
module: example_task
short_description: Get some really useful data from a library function
version_added: "0.1"
author: Micah R Ledbetter
"""
from ansible.module_utils import example_lib
from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec={
"arg1": {"type": "str"},
}
)
arg1 = module.params["arg1"]
try:
module.exit_json(
changed=False, result=example_lib.important_function_that_works_well(arg1)
)
except Exception as err:
module.fail_json(msg=str(err))
if __name__ == "__main__":
main()
example-playbook.yml
#
---
- hosts:
- host1.example.com
tasks:
- name: Do an example task
example_task:
arg1: "foobar"
register: example_result
- name: Show the example result
debug:
var: example_result
Example run log #
It might look like this. Some of Ansible’s output has been elided for clarity.
$ ansible-playbook example-playbook.yml
TASK [Do an example task] *****************************************************
ok: [host1.example.com]
Thursday 09 September 2021 17:00:20 -0500 (0:00:00.212) 0:00:05.522 ****
TASK [Show the example result] ************************************************
ok: [host1.example.com] =>
example_result:
changed: false
result: "foobar is my argument, wow what a useful function"
Thursday 09 September 2021 17:00:20 -0500 (0:00:00.212) 0:00:05.522 ****
module_utils
subdirectories
#
You can also use subdirectories of module_utils
.
For instance, module_utils/example_subdir/example_lib.py
can be imported in the task as
from ansible.module_utils.example_subdir import example_lib
.
Other topics #
TODO
Implement sections for testing, mypy, black, setup.py, commandline scripts, etc etc etc
- Include tests
- Type checked with
mypy
etc - Linted with
black
etc - Writing and runing tests
- Installed with
setup.py
according to good Python practice - Include commandline scripts that can call to exercise sections of the code as appropriate
- Show how to install them in to a venv with
pip -e
- Referencing packages in
module_utils
in modules and plugins - When to promote the generic code to a separate Python package, published to a pip server, and versioned, which can then be deployed to the Ansible controller for use