Enter Python Debugger From Running An Ansible Playbook
Enter the Python debugger from a running Ansible playbook#
I wanted access to pdb or ipdb while running a playbook that used custom modules. The Ansible developer guide has a section on debugging, but custom modules do not behave like normal Python files.
Ansible wraps modules with helper code and puts them into a zip file before execution. That makes normal interactive debugging awkward.
The Ansible documentation mentions simple debugging using epdb.
Simple debugging with epdb#
Install epdb into your virtual environment:
pip install epdb
Then add this line anywhere in the module where you have an issue.
import epdb; epdb.serve()
The line where you have the issue can usually be found by running your playbook in verbose mode:
ansible-playbook playbook.yml -vvvv
From the epdb docs:
To debug code that is either running on a remote system, or in a process that isn’t attached to your tty you can use epdb in server mode
Run your playbook and it should pause at that point. Connect with:
import epdb
epdb.connect()
This partly worked for me, but I could not control stepping. c, s, n and even h did not work, so I do not think it ever fully entered epdb.
One fallback is to raise an exception with the value you need. print() statements do not work reliably in modules.
raise Exception(some_value)
Debug strategy#
It depends on your play strategy.
Set
- hosts: all
connection: local
strategy: debug
It will then break on a failing task:
[localhost] TASK: create org (debug)>
You can then get the output of the json args sent to a module or task. Get the task arguments as JSON with:
{
'org_name': 'TEST0002',
'full_name': 'Test VCD ORG',
'is_enabled': 'true',
'state': 'present',
'_ansible_check_mode': False,
'_ansible_no_log': False,
'_ansible_debug': False,
'_ansible_diff': False,
'_ansible_verbosity': 0,
'_ansible_version': '2.9.7',
'_ansible_module_name': 'vcd_org',
'_ansible_syslog_facility': 'LOG_USER',
'_ansible_selinux_special_fs': ['fuse', 'nfs', 'vboxsf', 'ramfs', '9p', 'vfat'],
'_ansible_string_conversion_action': 'warn',
'_ansible_socket': None,
'_ansible_shell_executable': '/bin/sh',
'_ansible_keep_remote_files': False,
'_ansible_tmpdir': '/Users/stephen/.ansible/tmp/ansible-tmp-1588670617.1317708-64312-102300914438839/',
'_ansible_remote_tmp': '~/.ansible/tmp'
}
More options are available in the Ansible debugger docs.
Module utils#
Module utils can be accessed via ansible.module_utils.<your_name_here>.
When running the module directly, custom module utils might not be in the Python path and you can get an error:
python modules/vcd_org.py ./test_args.json
Traceback (most recent call last):
File "modules/vcd_org.py", line 102, in <module>
from ansible.module_utils.vcd import VcdAnsibleModule
ModuleNotFoundError: No module named 'ansible.module_utils.vcd'
To get the Ansible module utils search path:
ansible-config dump | grep MODULE_UTILS_PATH
It looks like a limitation of Ansible when bringing custom module_utils into direct module execution, as discussed in this Google Groups thread.
Workaround#
Copy the files from module_utils into your module library and update references from from ansible.module_utils.<package> to from <package>.