# Buggy code
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        policy_group=dict(
            type="str", aliases=["name", "policy_group_name"]
        ),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        # NOTE: Since this module needs to include both infra:AccBndlGrp (for PC and VPC) and infra:AccPortGrp (for leaf access port policy group):
        # NOTE: I'll allow the user to make the choice here (link(PC), node(VPC), leaf(leaf-access port policy group))
        lag_type=dict(
            type="str", aliases=["lag_type_name"], choices=["leaf", "link", "node"]
        ),  # Not required for querying all objects
        link_level_policy=dict(type="str", aliases=["link_level_policy_name"]),
        cdp_policy=dict(type="str", aliases=["cdp_policy_name"]),
        mcp_policy=dict(type="str", aliases=["mcp_policy_name"]),
        lldp_policy=dict(type="str", aliases=["lldp_policy_name"]),
        stp_interface_policy=dict(type="str", aliases=["stp_interface_policy_name"]),
        egress_data_plane_policing_policy=dict(
            type="str", aliases=["egress_data_plane_policing_policy_name"]
        ),
        ingress_data_plane_policing_policy=dict(
            type="str", aliases=["ingress_data_plane_policing_policy_name"]
        ),
        priority_flow_control_policy=dict(
            type="str", aliases=["priority_flow_control_policy_name"]
        ),
        fibre_channel_interface_policy=dict(
            type="str", aliases=["fibre_channel_interface_policy_name"]
        ),
        slow_drain_policy=dict(type="str", aliases=["slow_drain_policy_name"]),
        port_channel_policy=dict(type="str", aliases=["port_channel_policy_name"]),
        monitoring_policy=dict(type="str", aliases=["monitoring_policy_name"]),
        storm_control_interface_policy=dict(
            type="str", aliases=["storm_control_interface_policy_name"]
        ),
        l2_interface_policy=dict(type="str", aliases=["l2_interface_policy_name"]),
        port_security_policy=dict(type="str", aliases=["port_security_policy_name"]),
        aep=dict(type="str", aliases=["aep_name"]),
        state=dict(
            type="str", default="present", choices=["absent", "present", "query"]
        ),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["lag_type", "policy_group"]],
            ["state", "present", ["lag_type", "policy_group"]],
        ],
    )

    policy_group = module.params["policy_group"]
    description = module.params["description"]
    lag_type = module.params["lag_type"]
    link_level_policy = module.params["link_level_policy"]
    cdp_policy = module.params["cdp_policy"]
    mcp_policy = module.params["mcp_policy"]
    lldp_policy = module.params["lldp_policy"]
    stp_interface_policy = module.params["stp_interface_policy"]
    egress_data_plane_policing_policy = module.params[
        "egress_data_plane_policing_policy"
    ]
    ingress_data_plane_policing_policy = module.params[
        "ingress_data_plane_policing_policy"
    ]
    priority_flow_control_policy = module.params["priority_flow_control_policy"]
    fibre_channel_interface_policy = module.params["fibre_channel_interface_policy"]
    slow_drain_policy = module.params["slow_drain_policy"]
    port_channel_policy = module.params["port_channel_policy"]
    monitoring_policy = module.params["monitoring_policy"]
    storm_control_interface_policy = module.params["storm_control_interface_policy"]
    l2_interface_policy = module.params["l2_interface_policy"]
    port_security_policy = module.params["port_security_policy"]
    aep = module.params["aep"]
    state = module.params["state"]

    if lag_type == "leaf":
        aci_class_name = "infraAccPortGrp"
        dn_name = "accportgrp"
        class_config_dict = dict(
            name=policy_group,
            descr=description,
        )
    elif lag_type == "link" or lag_type == "node":
        aci_class_name = "infraAccBndlGrp"
        dn_name = "accbundle"
        class_config_dict = dict(
            name=policy_group,
            descr=description,
            lagT=lag_type,
        )

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=aci_class_name,
            aci_rn="infra/funcprof/{0}-{1}".format(dn_name, policy_group),
            filter_target='eq({0}.name, "{1}")'.format(aci_class_name, policy_group),
            module_object=policy_group,
        ),
        child_classes=[
            "infraRsAttEntP",
            "infraRsCdpIfPol",
            "infraRsFcIfPol",
            "infraRsHIfPol",
            "infraRsL2IfPol",
            "infraRsL2PortSecurityPol",
            "infraRsLacpPol",
            "infraRsLldpIfPol",
            "infraRsMcpIfPol",
            "infraRsMonIfInfraPol",
            "infraRsQosEgressDppIfPol",
            "infraRsQosIngressDppIfPol",
            "infraRsQosPfcIfPol",
            "infraRsQosSdIfPol",
            "infraRsStormctrlIfPol",
            "infraRsStpIfPol",
        ],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class=aci_class_name,
            class_config=class_config_dict,
            child_configs=[
                dict(
                    infraRsAttEntP=dict(
                        attributes=dict(
                            tDn="uni/infra/attentp-{0}".format(aep),
                        ),
                    ),
                ),
                dict(
                    infraRsCdpIfPol=dict(
                        attributes=dict(
                            tnCdpIfPolName=cdp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsFcIfPol=dict(
                        attributes=dict(
                            tnFcIfPolName=fibre_channel_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsHIfPol=dict(
                        attributes=dict(
                            tnFabricHIfPolName=link_level_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsL2IfPol=dict(
                        attributes=dict(
                            tnL2IfPolName=l2_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsL2PortSecurityPol=dict(
                        attributes=dict(
                            tnL2PortSecurityPolName=port_security_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsLacpPol=dict(
                        attributes=dict(
                            tnLacpLagPolName=port_channel_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsLldpIfPol=dict(
                        attributes=dict(
                            tnLldpIfPolName=lldp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsMcpIfPol=dict(
                        attributes=dict(
                            tnMcpIfPolName=mcp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsMonIfInfraPol=dict(
                        attributes=dict(
                            tnMonInfraPolName=monitoring_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosEgressDppIfPol=dict(
                        attributes=dict(
                            tnQosDppPolName=egress_data_plane_policing_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosIngressDppIfPol=dict(
                        attributes=dict(
                            tnQosDppPolName=ingress_data_plane_policing_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosPfcIfPol=dict(
                        attributes=dict(
                            tnQosPfcIfPolName=priority_flow_control_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosSdIfPol=dict(
                        attributes=dict(
                            tnQosSdIfPolName=slow_drain_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsStormctrlIfPol=dict(
                        attributes=dict(
                            tnStormctrlIfPolName=storm_control_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsStpIfPol=dict(
                        attributes=dict(
                            tnStpIfPolName=stp_interface_policy,
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class=aci_class_name)

        aci.post_config()

    elif state == "absent":
        aci.delete_config()

    aci.exit_json()


# Traceback (UnboundLocalError)
vagrant@ubuntu-xenial:~/vagrant_data/ansible$ ansible-playbook -i inventory_test aci-interface_policy_leaf_policy_group.yml --ask-vault-pass -vvvv
ansible-playbook 2.5.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
Vault password:
setting up inventory plugins
Parsed /home/vagrant/vagrant_data/ansible/inventory_test inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python2.7/dist-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: aci-interface_policy_leaf_policy_group.yml **********************************************************************************************************************************************
1 plays in aci-interface_policy_leaf_policy_group.yml

PLAY [PLAY - Leaf Policy Group viewer] ************************************************************************************************************************************************************
META: ran handlers
Trying secret <ansible.parsing.vault.PromptVaultSecret object at 0x7fb9ff1bf6d0> for vault_id=default

TASK [Query Leaf policy group] ********************************************************************************************************************************************************************
task path: /home/vagrant/vagrant_data/ansible/aci-interface_policy_leaf_policy_group.yml:11
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/network/aci/aci_interface_policy_leaf_policy_group.py
<10.112.129.173> ESTABLISH LOCAL CONNECTION FOR USER: vagrant
<10.112.129.173> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<10.112.129.173> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226 `" &amp;&amp; echo ansible-tmp-1526654733.34-184548725007226="` echo /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226 `" ) &amp;&amp; sleep 0'
<10.112.129.173> PUT /home/vagrant/.ansible/tmp/ansible-local-2790PDn11a/tmp2O3rgw TO /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226/aci_interface_policy_leaf_policy_group.py
<10.112.129.173> EXEC /bin/sh -c 'chmod u+x /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226/ /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226/aci_interface_policy_leaf_policy_group.py &amp;&amp; sleep 0'
<10.112.129.173> EXEC /bin/sh -c '/usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226/aci_interface_policy_leaf_policy_group.py &amp;&amp; sleep 0'
<10.112.129.173> EXEC /bin/sh -c 'rm -f -r /home/vagrant/.ansible/tmp/ansible-tmp-1526654733.34-184548725007226/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_v6lBN_/ansible_module_aci_interface_policy_leaf_policy_group.py", line 507, in <module>
main()
File "/tmp/ansible_v6lBN_/ansible_module_aci_interface_policy_leaf_policy_group.py", line 349, in main
aci_class=aci_class_name,
UnboundLocalError: local variable 'aci_class_name' referenced before assignment

fatal: [lab-aci]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_v6lBN_/ansible_module_aci_interface_policy_leaf_policy_group.py\", line 507, in <module>\n    main()\n  File \"/tmp/ansible_v6lBN_/ansible_module_aci_interface_policy_leaf_policy_group.py\", line 349, in main\n    aci_class=aci_class_name,\nUnboundLocalError: local variable 'aci_class_name' referenced before assignment\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}
to retry, use: --limit @/home/vagrant/vagrant_data/ansible/aci-interface_policy_leaf_policy_group.retry

PLAY RECAP ****************************************************************************************************************************************************************************************
lab-aci                    : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        policy_group=dict(
            type="str", aliases=["name", "policy_group_name"]
        ),  # Not required for querying all objects
        description=dict(type="str", aliases=["descr"]),
        # NOTE: Since this module needs to include both infra:AccBndlGrp (for PC and VPC) and infra:AccPortGrp (for leaf access port policy group):
        # NOTE: I'll allow the user to make the choice here (link(PC), node(VPC), leaf(leaf-access port policy group))
        lag_type=dict(
            type="str",
            required=True,
            aliases=["lag_type_name"],
            choices=["leaf", "link", "node"],
        ),
        link_level_policy=dict(type="str", aliases=["link_level_policy_name"]),
        cdp_policy=dict(type="str", aliases=["cdp_policy_name"]),
        mcp_policy=dict(type="str", aliases=["mcp_policy_name"]),
        lldp_policy=dict(type="str", aliases=["lldp_policy_name"]),
        stp_interface_policy=dict(type="str", aliases=["stp_interface_policy_name"]),
        egress_data_plane_policing_policy=dict(
            type="str", aliases=["egress_data_plane_policing_policy_name"]
        ),
        ingress_data_plane_policing_policy=dict(
            type="str", aliases=["ingress_data_plane_policing_policy_name"]
        ),
        priority_flow_control_policy=dict(
            type="str", aliases=["priority_flow_control_policy_name"]
        ),
        fibre_channel_interface_policy=dict(
            type="str", aliases=["fibre_channel_interface_policy_name"]
        ),
        slow_drain_policy=dict(type="str", aliases=["slow_drain_policy_name"]),
        port_channel_policy=dict(type="str", aliases=["port_channel_policy_name"]),
        monitoring_policy=dict(type="str", aliases=["monitoring_policy_name"]),
        storm_control_interface_policy=dict(
            type="str", aliases=["storm_control_interface_policy_name"]
        ),
        l2_interface_policy=dict(type="str", aliases=["l2_interface_policy_name"]),
        port_security_policy=dict(type="str", aliases=["port_security_policy_name"]),
        aep=dict(type="str", aliases=["aep_name"]),
        state=dict(
            type="str", default="present", choices=["absent", "present", "query"]
        ),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["policy_group"]],
            ["state", "present", ["policy_group"]],
        ],
    )

    policy_group = module.params["policy_group"]
    description = module.params["description"]
    lag_type = module.params["lag_type"]
    link_level_policy = module.params["link_level_policy"]
    cdp_policy = module.params["cdp_policy"]
    mcp_policy = module.params["mcp_policy"]
    lldp_policy = module.params["lldp_policy"]
    stp_interface_policy = module.params["stp_interface_policy"]
    egress_data_plane_policing_policy = module.params[
        "egress_data_plane_policing_policy"
    ]
    ingress_data_plane_policing_policy = module.params[
        "ingress_data_plane_policing_policy"
    ]
    priority_flow_control_policy = module.params["priority_flow_control_policy"]
    fibre_channel_interface_policy = module.params["fibre_channel_interface_policy"]
    slow_drain_policy = module.params["slow_drain_policy"]
    port_channel_policy = module.params["port_channel_policy"]
    monitoring_policy = module.params["monitoring_policy"]
    storm_control_interface_policy = module.params["storm_control_interface_policy"]
    l2_interface_policy = module.params["l2_interface_policy"]
    port_security_policy = module.params["port_security_policy"]
    aep = module.params["aep"]
    state = module.params["state"]

    if lag_type == "leaf":
        aci_class_name = "infraAccPortGrp"
        dn_name = "accportgrp"
        class_config_dict = dict(
            name=policy_group,
            descr=description,
        )
    elif lag_type in ("link", "node"):
        aci_class_name = "infraAccBndlGrp"
        dn_name = "accbundle"
        class_config_dict = dict(
            name=policy_group,
            descr=description,
            lagT=lag_type,
        )

    aci = ACIModule(module)
    aci.construct_url(
        root_class=dict(
            aci_class=aci_class_name,
            aci_rn="infra/funcprof/{0}-{1}".format(dn_name, policy_group),
            filter_target='eq({0}.name, "{1}")'.format(aci_class_name, policy_group),
            module_object=policy_group,
        ),
        child_classes=[
            "infraRsAttEntP",
            "infraRsCdpIfPol",
            "infraRsFcIfPol",
            "infraRsHIfPol",
            "infraRsL2IfPol",
            "infraRsL2PortSecurityPol",
            "infraRsLacpPol",
            "infraRsLldpIfPol",
            "infraRsMcpIfPol",
            "infraRsMonIfInfraPol",
            "infraRsQosEgressDppIfPol",
            "infraRsQosIngressDppIfPol",
            "infraRsQosPfcIfPol",
            "infraRsQosSdIfPol",
            "infraRsStormctrlIfPol",
            "infraRsStpIfPol",
        ],
    )

    aci.get_existing()

    if state == "present":
        aci.payload(
            aci_class=aci_class_name,
            class_config=class_config_dict,
            child_configs=[
                dict(
                    infraRsAttEntP=dict(
                        attributes=dict(
                            tDn="uni/infra/attentp-{0}".format(aep),
                        ),
                    ),
                ),
                dict(
                    infraRsCdpIfPol=dict(
                        attributes=dict(
                            tnCdpIfPolName=cdp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsFcIfPol=dict(
                        attributes=dict(
                            tnFcIfPolName=fibre_channel_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsHIfPol=dict(
                        attributes=dict(
                            tnFabricHIfPolName=link_level_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsL2IfPol=dict(
                        attributes=dict(
                            tnL2IfPolName=l2_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsL2PortSecurityPol=dict(
                        attributes=dict(
                            tnL2PortSecurityPolName=port_security_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsLacpPol=dict(
                        attributes=dict(
                            tnLacpLagPolName=port_channel_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsLldpIfPol=dict(
                        attributes=dict(
                            tnLldpIfPolName=lldp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsMcpIfPol=dict(
                        attributes=dict(
                            tnMcpIfPolName=mcp_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsMonIfInfraPol=dict(
                        attributes=dict(
                            tnMonInfraPolName=monitoring_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosEgressDppIfPol=dict(
                        attributes=dict(
                            tnQosDppPolName=egress_data_plane_policing_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosIngressDppIfPol=dict(
                        attributes=dict(
                            tnQosDppPolName=ingress_data_plane_policing_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosPfcIfPol=dict(
                        attributes=dict(
                            tnQosPfcIfPolName=priority_flow_control_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsQosSdIfPol=dict(
                        attributes=dict(
                            tnQosSdIfPolName=slow_drain_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsStormctrlIfPol=dict(
                        attributes=dict(
                            tnStormctrlIfPolName=storm_control_interface_policy,
                        ),
                    ),
                ),
                dict(
                    infraRsStpIfPol=dict(
                        attributes=dict(
                            tnStpIfPolName=stp_interface_policy,
                        ),
                    ),
                ),
            ],
        )

        aci.get_diff(aci_class=aci_class_name)

        aci.post_config()

    elif state == "absent":
        aci.delete_config()

    aci.exit_json()