# How to use \_ANSIBALLZ\_DEBUGPY\_CONFIG / debugpy to debug & develop ansible.netcommon network\_cli module

**URL:** <https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819>\
**Category:** Get Help\
**Tags:** ansible-devel, network\
**Created:** [November 9, 2025, 3:50pm UTC](https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819 "2025-11-09T15:50:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![trinitronx](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/trinitronx/32/4823_2.png) [@trinitronx](https://forum.ansible.com/u/trinitronx)\
**Post date:** [November 9, 2025, 3:50pm UTC](https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819/1 "2025-11-09T15:50:30Z")

</div>

While developing an Ansible module that uses `ansible.netcommon` / `network_cli` connection plugin, I need to debug what is going on with the connection flow and internal module, actions & plugin code. The particular combination of `AnsiballZ` zip file and local execution with Ansible `network_cli` connection type seems to add some extra complexity to navigate when trying to debug this.

[This guide gives some helpful instructions](https://www.automate.nyc/ansible/debug-ansible-module-with-vscode/). Yet, due to how `AnsiballZ` deals with the internal zipped module code paths seems to cause problems for the debugger when it tries to find the code files being executed.

I have instrumented my `network_cli` plugin code using `debugpy` like so:

```python
def run_commands(module, commands, check_rc=True):
    # BEGIN DEBUG INSTRUMENTATION
    import debugpy

    debugpy.listen(("0.0.0.0", 5678))
    debugpy.wait_for_client()
    debugpy.breakpoint()
    # END DEBUG INSTRUMENTATION

    connection = get_connection(module)
    try:
        return connection.run_commands(commands=commands, check_rc=check_rc)
    except ConnectionError as exc:
        module.fail_json(msg=to_text(exc))

```

`.vscode/launch.json`:

```auto
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debugger: Remote Attach",
            "type": "debugpy",
            "request": "attach",
            "connect": {
                "host": "127.0.0.1",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "${workspaceFolder}" // does not work
                    // "remoteRoot": "." // also did not work
                    // Maybe a hack like this could work... but the tmp dir is random at runtime...
                    // "remoteRoot": "/tmp/ansible_lyraphase.opnsense.facts_payload_XXXXXXXX/ansible_lyraphase.opnsense.facts_payload.zip/.../path/to/local/python/code"
                }
            ]
        }
    ]
}

```

When I try each of the following, I run into a different roadblock:

1. Running the `debugpy`-instrumented module via a playbook seems to work, but paths are given within a random temporary directory path, and within the `Ansiballz` `payload.zip`. Thus, VSCode debugger fails to find the local python file path to debug. For example:

2. Unpacking the module and running it manually (as in the [previously mentioned guide](https://www.automate.nyc/ansible/debug-ansible-module-with-vscode/)) results in an error when the temporary Ansible connection socket is not found:

> **Expand for stacktrace with newlines rendered**
>
> ```auto
> File "/home/exampleuser/src/pub/ansible/lyraphase-ansible-playbooks/tmp/debug_dir/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/network.py", line 217, in get_capabilities
> capabilities = Connection(module._socket_path).get_capabilities()
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/home/exampleuser/src/pub/ansible/lyraphase-ansible-playbooks/tmp/debug_dir/ansible/module_utils/connection.py", line 177, in __rpc__
> response = self._exec_jsonrpc(name, *args, **kwargs)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/home/exampleuser/src/pub/ansible/lyraphase-ansible-playbooks/tmp/debug_dir/ansible/module_utils/connection.py", line 124, in _exec_jsonrpc
> raise ConnectionError(
> ", "invocation": {"module_args": {"gather_subset": ["default"], "gather_network_resources": null, "opnsense_shell_option": null, "passwords": null}}}
> 
> ```

The first case seems to work, as the VSCode debugger can connect to `debugpy` server port `5678`, and the breakpoint, variables, and call stack are visible in the VSCode debug UI. Yet, the python code file cannot be found to show the currently executing line to step through.

The second case (`explode` + `execute`) fails because it expects Ansible to have setup a socket file (via [`task_executor.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/executor/task_executor.py) + [`ansible_connection_cli_stub.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/scripts/ansible_connection_cli_stub.py) perhaps?)

Searching through Ansible’s source code, I found [mention of an environment variable that seems related to this](https://github.com/ansible/ansible/blob/devel/lib/ansible/config/base.yml#L14-L18): `_ANSIBALLZ_DEBUGPY_CONFIG`

> ```auto
> _ANSIBALLZ_DEBUGPY_CONFIG:
> name: Configure the AnsiballZ remote debugging extension for debugpy
> description:
> - Enables and configures the AnsiballZ remote debugging extension for debugpy.
> - This is for internal use only.
> 
> ```

How can this be used to configure `debugpy` for debugging of `AnsiballZ`-packed code?

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [November 10, 2025, 9:25pm UTC](https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819/2 "2025-11-10T21:25:46Z")

</div>

> \_ANSIBALLZ\_DEBUGPY\_CONFIG

This is a newly released feature that is mostly kept as an internal API but have currently exposed a more public interface through `ansible-test` and the `--dev-debug-on-demand` argument. To use this in VSCode try to run this launch configuration

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "ansible-test shell module debugging",
            "type": "debugpy",
            "request": "launch",
            "module": "ansible",
            "args": ["test", "shell", "--dev-debug-on-demand"]
        },
    ]
}

```

This will launch an interactive shell in VSCode that has set the env var `_ANSIBALLZ_DEBUGPY_CONFIG` with the required values needed for Ansible to attach back to the running debug session like the below.

 ![image](https://us1.discourse-cdn.com/ansible/original/2X/7/76984f48c7c7908a453ecd62fbc4617cd66682c4.png)

I ran the above launch configuration then in the terminal below I just ran `ansible localhost -m ping` and the breakpoint I have set in the `ping.py` module is hit when run. It deals with all the required path mappings for you and you can step through the code, including action plugins, the main Ansible process, any worker code, plus the module execution.

What I have no tested is this with networking modules. There’s a chance that this doesn’t work as I’ve not got an environment to test them against and there’s a chance that how the modules are run won’t work with how this is all setup. But AFAIK for networking, the module code is run on `localhost` so the existing `ansible-test shell --dev-debug-on-demand` should just have it all hooked up to work normally. If it doesn’t we can certainly try and look into what’s happening to make it work.

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [November 10, 2025, 9:28pm UTC](https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819/3 "2025-11-10T21:28:00Z")

</div>

I forgot to mention, you can manually set this config and setup the required debug server. The documentation for this config option is found in [ansible/lib/ansible/module\_utils/\_internal/\_ansiballz/\_extensions/\_debugpy.py at 89ba882b085a47a8cd064972dfe3348249652686 · ansible/ansible · GitHub](https://github.com/ansible/ansible/blob/89ba882b085a47a8cd064972dfe3348249652686/lib/ansible/module_utils/_internal/_ansiballz/_extensions/_debugpy.py#L10-L47) and shows you a launch configuration that sets up a `debugpy` listener and a configuration that launches your playbook (or adhoc command) to connect back to that listener. Please keep in mind this is not a public API and is subject to change.

---

<div class="post-metadata">

**Author:** ![trinitronx](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/trinitronx/32/4823_2.png) [@trinitronx](https://forum.ansible.com/u/trinitronx)\
**Post date:** [November 22, 2025, 7:38am UTC](https://forum.ansible.com/t/how-to-use-ansiballz-debugpy-config-debugpy-to-debug-develop-ansible-netcommon-network-cli-module/44819/4 "2025-11-22T07:38:03Z")

</div>

Thanks for this excellent explanation of how to use this! It’s really helpful to demystify how to use this new internal developer-facing (and of course _unstable_) debugger API.

In my case, I had been trying to debug my custom collection network module using either a testing playbook or trying `integration` or `network-integration` test runs using `ansible-test`.

> [@jborean](#):
>
> But AFAIK for networking, the module code is run on `localhost` so the existing `ansible-test shell --dev-debug-on-demand` should just have it all hooked up to work normally. If it doesn’t we can certainly try and look into what’s happening to make it work.

So, evidently in my case I ran into a few roadblocks while using `ansible-test`, but for another semi-related reason. After a few days of tinkering with this and testing… it turns out that there are [a few places](https://github.com/ansible/ansible/blob/bff3a9aeb91a19e42befd1f6839dfa6984f4d1ea/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py#L14-L32) in `ansible-test`’s [`pytest` plugin code where `ANSIBLE_COLLECTIONS_PATH` is handled](https://github.com/ansible/ansible/blob/bff3a9aeb91a19e42befd1f6839dfa6984f4d1ea/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py#L92) as if it were **_always_ a single path**.

Likewise, there is a similar issue with how `ANSIBLE_COLLECTIONS_PATH` is set to a single root path by the generic `ansible-test` [`integration`, `network-integration`, `sanity`, etc…] command code paths in [`ansible_test._internal.ansible_util.ansible_environment()` here](https://github.com/ansible/ansible/blob/bff3a9aeb91a19e42befd1f6839dfa6984f4d1ea/test/lib/ansible_test/_internal/ansible_util.py#L143).

This probably works for testing generic collections which have no other dependencies. However, in my case, the networking module I’m working on had dependencies (`ansible.netcommon`, `ansible.utils`) which were not being found in the single temporary directory which `ansible-test` was copying my collection + modules into and setting `ANSIBLE_COLLECTIONS_PATH` to use when running `pytest` or `integration` / `network-integration` tests.

So, `ansible-test` was throwing stacktraces when collection dependencies or contained plugin libraries were not found.

I pushed up a PR to fix the [`ansible-test` `pytest` plugin issue here (ansible/ansible#86239)](https://github.com/ansible/ansible/pull/86239).
