# Buggy code
def populate_ipv6_interfaces(self, data):
    for key, value in iteritems(data):
        self.facts["interfaces"][key]["ipv6"] = list()
        addresses = re.findall(r"\s+(.+), subnet", value, re.M)
        subnets = re.findall(r", subnet is (.+)$", value, re.M)
        for addr, subnet in zip(addresses, subnets):
            ipv6 = dict(address=addr.strip(), subnet=subnet.strip())
            self.add_ip_address(addr.strip(), "ipv6")
            self.facts["interfaces"][key]["ipv6"].append(ipv6)


# Traceback (KeyError)
TASK [Get Cisco Facts] ***************************************************************************************************************************
task path: /opt/ansible/cisco-router.yaml:20
<cisco_rtr1> using connection plugin network_cli
<cisco_rtr1> socket_path: /home/usertest/.ansible/pc/23176f0a55
open_shell() returned 0 ok
Using module file /opt/virtualenvs/ansiblerun/lib/python2.7/site-packages/ansible/modules/network/ios/ios_facts.py
<cisco_rtr1> ESTABLISH LOCAL CONNECTION FOR USER: usertest
<cisco_rtr1> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<cisco_rtr1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600 `" &amp;&amp; echo ansible-tmp-1500908715.18-68393613750600="` echo /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600 `" ) &amp;&amp; sleep 0'
<cisco_rtr1> PUT /tmp/tmpRQRKJf TO /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600/ios_facts.py
<cisco_rtr1> EXEC /bin/sh -c 'chmod u+x /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600/ /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600/ios_facts.py &amp;&amp; sleep 0'
<cisco_rtr1> EXEC /bin/sh -c '/usr/bin/python /home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600/ios_facts.py; rm -rf "/home/usertest/.ansible/tmp/ansible-tmp-1500908715.18-68393613750600/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_POLuRN/ansible_module_ios_facts.py", line 489, in <module>
main()
File "/tmp/ansible_POLuRN/ansible_module_ios_facts.py", line 474, in main
inst.populate()
File "/tmp/ansible_POLuRN/ansible_module_ios_facts.py", line 269, in populate
self.populate_ipv6_interfaces(data)
File "/tmp/ansible_POLuRN/ansible_module_ios_facts.py", line 302, in populate_ipv6_interfaces
self.facts['interfaces'][key]['ipv6'] = list()
KeyError: 'VoIP-Null0'

fatal: [cisco_rtr1]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_POLuRN/ansible_module_ios_facts.py\", line 489, in <module>\n    main()\n  File \"/tmp/ansible_POLuRN/ansible_module_ios_facts.py\", line 474, in main\n    inst.populate()\n  File \"/tmp/ansible_POLuRN/ansible_module_ios_facts.py\", line 269, in populate\n    self.populate_ipv6_interfaces(data)\n  File \"/tmp/ansible_POLuRN/ansible_module_ios_facts.py\", line 302, in populate_ipv6_interfaces\n    self.facts['interfaces'][key]['ipv6'] = list()\nKeyError: 'VoIP-Null0'\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}
to retry, use: --limit @/opt/ansible/cisco-router.retry

# Fixed code
def populate_ipv6_interfaces(self, data):
    for key, value in iteritems(data):
        try:
            self.facts["interfaces"][key]["ipv6"] = list()
        except KeyError:
            self.facts["interfaces"][key] = dict()
            self.facts["interfaces"][key]["ipv6"] = list()
        addresses = re.findall(r"\s+(.+), subnet", value, re.M)
        subnets = re.findall(r", subnet is (.+)$", value, re.M)
        for addr, subnet in zip(addresses, subnets):
            ipv6 = dict(address=addr.strip(), subnet=subnet.strip())
            self.add_ip_address(addr.strip(), "ipv6")
            self.facts["interfaces"][key]["ipv6"].append(ipv6)