Debugging modules
- Set a breakpoint in the module:
import pdb; pdb.set_trace()
echo ‘{“msg”: “hello”}’ | python ./my_new_test_module.py
To debug a module running on a remote target (i.e. not localhost
):
- On your controller machine (running Ansible) set
ANSIBLE_KEEP_REMOTE_FILES=1
to tell Ansible to retain the modules it sends to the remote machine instead of removing them after you playbook runs. - Run your playbook targeting the remote machine and specify
-vvvv
(verbose) to display the remote location Ansible is using for the modules (among many other things). - Take note of the directory Ansible used to store modules on the remote host. This directory is usually under the home directory of your
ansible_user
, in the form~/.ansible/tmp/ansible-tmp-…
. - SSH into the remote target after the playbook runs.
- Navigate to the directory you noted in step 3.
- Navigate to the debug directory:
$ cd debug-dir
. - Modify or set a breakpoint in .
- Ensure that the unzipped module is executable:
$ chmod 755 main.py
. - Run the unzipped module directly, passing the
args
file that contains the params that were originally passed:$ ./main.py args
. This approach is good for reproducing behavior as well as modifying the parameters for debugging.
Tip
Starting with Ansible 2.1, AnsibleModule-based modules are put together asa zip file consisting of the module file and the various python moduleboilerplate inside of a wrapper script instead of as a single file with all ofthe code concatenated together. Without some help, this can be harder todebug as the file needs to be extracted from the wrapper in order to seewhat’s actually going on in the module. Luckily the wrapper script providessome helper methods to do just that.
If you are using Ansible with the ANSIBLE_KEEP_REMOTE_FILES
environment variables to keep the remote module file, here’s a sample of howyour debugging session will start:
Setting to 1
tells Ansible to keep theremote module files instead of deleting them after the module finishesexecuting. Giving Ansible the -vvv
option makes Ansible more verbose.That way it prints the file name of the temporary module file for you to see.
When you look into the debug_dir you’ll see a directory structure like this:
ansible_module_ping.py
is the code for the module itself. The nameis based on the name of the module with a prefix so that we don’t clash withany other python module names. You can modify this code to see what effectit would have on your module.- The directory contains code from
ansible.module_utils
that is used by the module. Ansible includesfiles for any imports in the module but notany files from any other module. So if your module usesansible.module_utils.url
Ansible will include it for you, but ifyour module includes then you’ll have to make sure thatthe python requests library is installed on the system before running themodule. You can modify files in this directory if you suspect that themodule is having a problem in some of this boilerplate code rather than inthe module code you have written.
Once you edit the code or arguments in the exploded tree you need some way torun it. There’s a separate wrapper subcommand for this:
This subcommand takes care of setting the PYTHONPATH to use the explodeddebug_dir/ansible/module_utils
directory and invoking the script usingthe arguments in the args
file. You can continue to run it like thisuntil you understand the problem. Then you can copy it back into your realmodule file and test that the real module works via ansible oransible-playbook.
The wrapper provides one more subcommand, excommunicate
. Thissubcommand is very similar to execute
in that it invokes the explodedmodule on the arguments in the args
. The way it does this isdifferent, however. excommunicate
imports the main
function from the module and then calls that. This makes excommunicateexecute the module in the wrapper’s process. This may be useful forrunning the module under some graphical debuggers but it is very differentfrom the way the module is executed by Ansible itself. Some modules maynot work with excommunicate
or may behave differently than when usedwith Ansible normally. Those are not bugs in the module; they’relimitations of . Use at your own risk.