# Buggy code
def run(self, tmp=None, task_vars=None):
    if self._task.args.get("src"):
        try:
            self._handle_template()
        except ValueError as exc:
            return dict(failed=True, msg=exc.message)

    result = super(ActionModule, self).run(tmp, task_vars)
    del tmp  # tmp no longer has any effect

    if self._task.args.get("backup") and result.get("__backup__"):
        # User requested backup and no error occurred in module.
        # NOTE: If there is a parameter error, _backup key may not be in results.
        filepath = self._write_backup(
            task_vars["inventory_hostname"], result["__backup__"]
        )

        result["backup_path"] = filepath

    # strip out any keys that have two leading and two trailing
    # underscore characters
    for key in result.keys():
        if PRIVATE_KEYS_RE.match(key):
            del result[key]

    return result


# Traceback (RuntimeError)
user@somewhere:~/git/noc-docs/ansible/playbooks$ ansible-playbook onyx_config.yml  -vvvv
ansible-playbook 2.5.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.5/dist-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 3.5.3 (default, Jan 19 2017, 14:11:04) [GCC 6.3.0 20170118]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /home/user/git/noc-docs/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python3.5/dist-packages/ansible/plugins/callback/default.py

PLAYBOOK: onyx_config.yml ***************************************************************************************************************************************************************
1 plays in onyx_config.yml

PLAY [mlnx_os] **************************************************************************************************************************************************************************
META: ran handlers

TASK [change config on MLNX-OS device] **************************************************************************************************************************************************
task path: /home/user/git/noc-docs/ansible/playbooks/onyx_config.yml:7
<1.1.1.1> attempting to start connection
<1.1.1.1> using connection plugin network_cli
<2.2.2.2> attempting to start connection
<2.2.2.2> using connection plugin network_cli
<1.1.1.1> local domain socket does not exist, starting it
<1.1.1.1> control socket path is /home/user/.ansible/pc/e7d6fea450
<1.1.1.1> <1.1.1.1> ESTABLISH CONNECTION FOR USER: None on PORT 22 TO 1.1.1.1
<1.1.1.1> <1.1.1.1> ssh connection done, setting terminal
<1.1.1.1> <1.1.1.1> loaded terminal plugin for network_os onyx
<1.1.1.1> <1.1.1.1> loaded cliconf plugin for network_os onyx
<1.1.1.1> <1.1.1.1> firing event: on_open_shell()
<1.1.1.1> <1.1.1.1> firing event: on_become
<1.1.1.1> <1.1.1.1> ssh connection has completed successfully
<1.1.1.1> connection to remote device started successfully
<1.1.1.1> local domain socket listeners started successfully
<1.1.1.1>
<1.1.1.1> local domain socket path is /home/user/.ansible/pc/e7d6fea450
Using module file /usr/local/lib/python3.5/dist-packages/ansible/modules/network/onyx/onyx_config.py
<1.1.1.1> ESTABLISH LOCAL CONNECTION FOR USER: user
<1.1.1.1> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<1.1.1.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447 `" &amp;&amp; echo ansible-tmp-1522919162.2716436-173180906683447="` echo /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447 `" ) &amp;&amp; sleep 0'
<1.1.1.1> PUT /home/user/.ansible/tmp/ansible-local-104891g0op533/tmpffkdau9n TO /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447/onyx_config.py
<1.1.1.1> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447/ /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447/onyx_config.py &amp;&amp; sleep 0'
<1.1.1.1> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447/onyx_config.py &amp;&amp; sleep 0'
<2.2.2.2> local domain socket does not exist, starting it
<2.2.2.2> control socket path is /home/user/.ansible/pc/89c607bbb3
<2.2.2.2> <2.2.2.2> ESTABLISH CONNECTION FOR USER: None on PORT 22 TO 2.2.2.2
<2.2.2.2> <2.2.2.2> ssh connection done, setting terminal
<2.2.2.2> <2.2.2.2> loaded terminal plugin for network_os onyx
<2.2.2.2> <2.2.2.2> loaded cliconf plugin for network_os onyx
<2.2.2.2> <2.2.2.2> firing event: on_open_shell()
<2.2.2.2> <2.2.2.2> firing event: on_become
<2.2.2.2> <2.2.2.2> ssh connection has completed successfully
<2.2.2.2> connection to remote device started successfully
<2.2.2.2> local domain socket listeners started successfully
<2.2.2.2>
<2.2.2.2> local domain socket path is /home/user/.ansible/pc/89c607bbb3
Using module file /usr/local/lib/python3.5/dist-packages/ansible/modules/network/onyx/onyx_config.py
<2.2.2.2> ESTABLISH LOCAL CONNECTION FOR USER: user
<2.2.2.2> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<2.2.2.2> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161 `" &amp;&amp; echo ansible-tmp-1522919171.0372546-12351055057161="` echo /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161 `" ) &amp;&amp; sleep 0'
<2.2.2.2> PUT /home/user/.ansible/tmp/ansible-local-104891g0op533/tmp6wz2e7ji TO /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161/onyx_config.py
<2.2.2.2> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161/ /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161/onyx_config.py &amp;&amp; sleep 0'
<2.2.2.2> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161/onyx_config.py &amp;&amp; sleep 0'
<1.1.1.1> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1522919162.2716436-173180906683447/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/ansible/executor/task_executor.py", line 138, in run
res = self._execute()
File "/usr/local/lib/python3.5/dist-packages/ansible/executor/task_executor.py", line 554, in _execute
result = self._handler.run(task_vars=variables)
File "/usr/local/lib/python3.5/dist-packages/ansible/plugins/action/onyx_config.py", line 57, in run
for key in result.keys():
RuntimeError: dictionary changed size during iteration

fatal: [1.1.1.1]: FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
}
<2.2.2.2> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1522919171.0372546-12351055057161/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/ansible/executor/task_executor.py", line 138, in run
res = self._execute()
File "/usr/local/lib/python3.5/dist-packages/ansible/executor/task_executor.py", line 554, in _execute
result = self._handler.run(task_vars=variables)
File "/usr/local/lib/python3.5/dist-packages/ansible/plugins/action/onyx_config.py", line 57, in run
for key in result.keys():
RuntimeError: dictionary changed size during iteration

fatal: [2.2.2.2]: FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
}
to retry, use: --limit @/home/user/git/noc-docs/ansible/playbooks/onyx_config.retry

PLAY RECAP ******************************************************************************************************************************************************************************
1.1.1.1              : ok=0    changed=0    unreachable=0    failed=1
2.2.2.2              : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def run(self, tmp=None, task_vars=None):
    if self._task.args.get("src"):
        try:
            self._handle_template()
        except ValueError as exc:
            return dict(failed=True, msg=exc.message)

    result = super(ActionModule, self).run(tmp, task_vars)
    del tmp  # tmp no longer has any effect

    if self._task.args.get("backup") and result.get("__backup__"):
        # User requested backup and no error occurred in module.
        # NOTE: If there is a parameter error, _backup key may not be in results.
        filepath = self._write_backup(
            task_vars["inventory_hostname"], result["__backup__"]
        )

        result["backup_path"] = filepath

    # strip out any keys that have two leading and two trailing
    # underscore characters
    for key in list(result.keys()):
        if PRIVATE_KEYS_RE.match(key):
            del result[key]

    return result