# Buggy code
def get_target_group_attributes(connection, module, target_group_arn):
    try:
        target_group_attributes = boto3_tag_list_to_ansible_dict(
            connection.describe_target_group_attributes(
                TargetGroupArn=target_group_arn
            )["Attributes"]
        )
    except ClientError as e:
        module.fail_json(
            msg=e.message,
            exception=traceback.format_exc(),
            **camel_dict_to_snake_dict(e.response),
        )

    # Replace '.' with '_' in attribute key names to make it more Ansibley
    for k, v in target_group_attributes.items():
        target_group_attributes[k.replace(".", "_")] = v
        del target_group_attributes[k]

    return target_group_attributes


# Traceback (RuntimeError)
ansible-playbook 2.5.0 (devel adc533804a) last updated 2017/09/12 14:51:23 (GMT -200)
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/gustavo/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /home/gustavo/Documents/Tools/Ansible/source/ansible/lib/ansible
executable location = /home/gustavo/Documents/Tools/Ansible/source/ansible/bin/ansible-playbook
python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Set default localhost to localhost
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: Found both group and host with same name: nexus

[WARNING]: Found both group and host with same name: sonar

[WARNING]: Found both group and host with same name: ci-server

[WARNING]: Found both group and host with same name: rundeck

Loading callback plugin default of type stdout, v2.0 from /home/gustavo/Documents/Tools/Ansible/source/ansible/lib/ansible/plugins/callback/__init__.pyc

PLAYBOOK: test.yml ***********************************************************************************************************************************************************************************************************************************************************************************************************
clear: <built-in method clear of dict object at 0x7f4c96e49398>
copy: <built-in method copy of dict object at 0x7f4c96e49398>
fromkeys: <built-in method fromkeys of type object at 0x906f00>
get: <built-in method get of dict object at 0x7f4c96e49398>
has_key: <built-in method has_key of dict object at 0x7f4c96e49398>
items: <built-in method items of dict object at 0x7f4c96e49398>
iteritems: <built-in method iteritems of dict object at 0x7f4c96e49398>
iterkeys: <built-in method iterkeys of dict object at 0x7f4c96e49398>
itervalues: <built-in method itervalues of dict object at 0x7f4c96e49398>
keys: <built-in method keys of dict object at 0x7f4c96e49398>
pop: <built-in method pop of dict object at 0x7f4c96e49398>
popitem: <built-in method popitem of dict object at 0x7f4c96e49398>
setdefault: <built-in method setdefault of dict object at 0x7f4c96e49398>
update: <built-in method update of dict object at 0x7f4c96e49398>
values: <built-in method values of dict object at 0x7f4c96e49398>
viewitems: <built-in method viewitems of dict object at 0x7f4c96e49398>
viewkeys: <built-in method viewkeys of dict object at 0x7f4c96e49398>
viewvalues: <built-in method viewvalues of dict object at 0x7f4c96e49398>
1 plays in test.yml

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

TASK [elb_target_group_facts] ************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/gustavo/Documents/enkel/clientes/smiles/agile/playbooks/ecs/smiles-ansible-role-ecs-service/test.yml:4
Using module file /home/gustavo/Documents/Tools/Ansible/source/ansible/lib/ansible/modules/cloud/amazon/elb_target_group_facts.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: gustavo
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918 `" &amp;&amp; echo ansible-tmp-1505239382.8-235079325159918="` echo /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918 `" ) &amp;&amp; sleep 0'
<localhost> PUT /tmp/tmpxQNS9D TO /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918/elb_target_group_facts.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918/ /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918/elb_target_group_facts.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python3 /home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918/elb_target_group_facts.py; rm -rf "/home/gustavo/.ansible/tmp/ansible-tmp-1505239382.8-235079325159918/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py", line 270, in <module>
main()
File "/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py", line 266, in main
list_target_groups(connection, module)
File "/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py", line 228, in list_target_groups
target_group.update(get_target_group_attributes(connection, module, target_group['TargetGroupArn']))
File "/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py", line 187, in get_target_group_attributes
for k, v in target_group_attributes.items():
RuntimeError: dictionary changed size during iteration

fatal: [localhost]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py\", line 270, in <module>\n    main()\n  File \"/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py\", line 266, in main\n    list_target_groups(connection, module)\n  File \"/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py\", line 228, in list_target_groups\n    target_group.update(get_target_group_attributes(connection, module, target_group['TargetGroupArn']))\n  File \"/tmp/ansible_xlul11km/ansible_module_elb_target_group_facts.py\", line 187, in get_target_group_attributes\n    for k, v in target_group_attributes.items():\nRuntimeError: dictionary changed size during iteration\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}
to retry, use: --limit @/home/gustavo/Documents/enkel/clientes/smiles/agile/playbooks/ecs/smiles-ansible-role-ecs-service/test.retry

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def get_target_group_attributes(connection, module, target_group_arn):
    try:
        target_group_attributes = boto3_tag_list_to_ansible_dict(
            connection.describe_target_group_attributes(
                TargetGroupArn=target_group_arn
            )["Attributes"]
        )
    except ClientError as e:
        module.fail_json(
            msg=e.message,
            exception=traceback.format_exc(),
            **camel_dict_to_snake_dict(e.response),
        )

    # Replace '.' with '_' in attribute key names to make it more Ansibley
    return dict((k.replace(".", "_"), v) for (k, v) in target_group_attributes.items())