# Buggy code
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(
            type="str", aliases=["tenant_name"]
        ),  # Not required for querying all objects
        l3out=dict(
            type="str", aliases=["l3out_name", "name"]
        ),  # Not required for querying all objects
        domain=dict(type="str", aliases=["ext_routed_domain_name", "routed_domain"]),
        vrf=dict(type="str", aliases=["vrf_name"]),
        description=dict(type="str", aliases=["descr"]),
        route_control=dict(
            type="list",
            choices=["export", "import"],
            aliases=["route_control_enforcement"],
        ),
        dscp=dict(
            type="str",
            choices=[
                "AF11",
                "AF12",
                "AF13",
                "AF21",
                "AF22",
                "AF23",
                "AF31",
                "AF32",
                "AF33",
                "AF41",
                "AF42",
                "AF43",
                "CS0",
                "CS1",
                "CS2",
                "CS3",
                "CS4",
                "CS5",
                "CS6",
                "CS7",
                "EF",
                "VA",
                "unspecified",
            ],
            aliases=["target"],
        ),
        l3protocol=dict(type="list", choices=["bgp", "eigrp", "ospf", "pim", "static"]),
        asn=dict(type="int", aliases=["as_number"]),
        state=dict(
            type="str", default="present", choices=["absent", "present", "query"]
        ),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["l3out", "tenant"]],
            ["state", "present", ["l3out", "tenant", "domain", "vrf"]],
        ],
    )

    aci = ACIModule(module)

    l3out = module.params["l3out"]
    domain = module.params["domain"]
    dscp = module.params["dscp"]
    description = module.params["description"]
    enforceRtctrl = module.params["route_control"]
    vrf = module.params["vrf"]
    l3protocol = module.params["l3protocol"]
    asn = module.params["asn"]
    state = module.params["state"]
    tenant = module.params["tenant"]

    if "eigrp" in l3protocol and asn is None:
        module.fail_json(msg="Parameter 'asn' is required when l3protocol is 'eigrp'")
    if "eigrp" not in l3protocol and asn is not None:
        module.warn(
            "Parameter 'asn' is only applicable when l3protocol is 'eigrp'. The ASN will be ignored"
        )

    enforce_ctrl = ""
    if enforceRtctrl is not None:
        if len(enforceRtctrl) == 1 and enforceRtctrl[0] == "import":
            aci.fail_json(
                "The route_control parameter is invalid: allowed options are export or import,export only"
            )
        elif len(enforceRtctrl) == 1 and enforceRtctrl[0] == "export":
            enforce_ctrl = "export"
        else:
            enforce_ctrl = "export,import"
    child_classes = [
        "l3extRsL3DomAtt",
        "l3extRsEctx",
        "bgpExtP",
        "ospfExtP",
        "eigrpExtP",
        "pimExtP",
    ]

    aci.construct_url(
        root_class=dict(
            aci_class="fvTenant",
            aci_rn="tn-{0}".format(tenant),
            module_object=tenant,
            target_filter={"name": tenant},
        ),
        subclass_1=dict(
            aci_class="l3extOut",
            aci_rn="out-{0}".format(l3out),
            module_object=l3out,
            target_filter={"name": l3out},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    child_configs = [
        dict(l3extRsL3DomAtt=dict(attributes=dict(tDn="uni/l3dom-{0}".format(domain)))),
        dict(l3extRsEctx=dict(attributes=dict(tnFvCtxName=vrf))),
    ]
    if l3protocol is not None:
        for protocol in l3protocol:
            if protocol == "bgp":
                child_configs.append(
                    dict(bgpExtP=dict(attributes=dict(descr="", nameAlias="")))
                )
            elif protocol == "eigrp":
                child_configs.append(
                    dict(
                        eigrpExtP=dict(attributes=dict(descr="", nameAlias="", asn=asn))
                    )
                )
            elif protocol == "ospf":
                child_configs.append(
                    dict(ospfExtP=dict(attributes=dict(descr="", nameAlias="")))
                )
            elif protocol == "pim":
                child_configs.append(
                    dict(pimExtP=dict(attributes=dict(descr="", nameAlias="")))
                )

    if state == "present":
        aci.payload(
            aci_class="l3extOut",
            class_config=dict(
                name=l3out,
                descr=description,
                dn="uni/tn-{0}/out-{1}".format(tenant, l3out),
                enforceRtctrl=enforce_ctrl,
                targetDscp=dscp,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="l3extOut")

        aci.post_config()

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

    aci.exit_json()


# Traceback (nTypeError)
ansible-playbook -i hosts delete_l3out_test.yml --ask-vault
Vault password:

PLAY [Delete a L3out] ******************************************************************************************************************

TASK [Get creds from vault] ************************************************************************************************************
ok: [10.10.250.55]

TASK [Delete L3Out] ********************************************************************************************************************
fatal: [10.10.250.55]: FAILED! => {"changed": false, "module_stderr": "/Users/mmullen/.ansible/tmp/ansible-tmp-1560280130.771988-253530270617295/AnsiballZ_aci_l3out.py:18: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n  import imp\nTraceback (most recent call last):\n  File \"/Users/mmullen/.ansible/tmp/ansible-tmp-1560280130.771988-253530270617295/AnsiballZ_aci_l3out.py\", line 114, in <module>\n    _ansiballz_main()\n  File \"/Users/mmullen/.ansible/tmp/ansible-tmp-1560280130.771988-253530270617295/AnsiballZ_aci_l3out.py\", line 106, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/Users/mmullen/.ansible/tmp/ansible-tmp-1560280130.771988-253530270617295/AnsiballZ_aci_l3out.py\", line 49, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/Users/mmullen/.pyenv/versions/3.7.2/lib/python3.7/imp.py\", line 234, in load_module\n    return load_source(name, filename, file)\n  File \"/Users/mmullen/.pyenv/versions/3.7.2/lib/python3.7/imp.py\", line 169, in load_source\n    module = _exec(spec, sys.modules[name])\n  File \"<frozen importlib._bootstrap>\", line 630, in _exec\n  File \"<frozen importlib._bootstrap_external>\", line 728, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\n  File \"/var/folders/sh/7v2wynys2ys35n61fcgt3zm00000gn/T/ansible_aci_l3out_payload_zsmg_mwe/__main__.py\", line 361, in <module>\n  File \"/var/folders/sh/7v2wynys2ys35n61fcgt3zm00000gn/T/ansible_aci_l3out_payload_zsmg_mwe/__main__.py\", line 283, in main\nTypeError: argument of type 'NoneType' is not iterable\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP *****************************************************************************************************************************
10.10.250.55               : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

# Fixed code
def main():
    argument_spec = aci_argument_spec()
    argument_spec.update(
        tenant=dict(
            type="str", aliases=["tenant_name"]
        ),  # Not required for querying all objects
        l3out=dict(
            type="str", aliases=["l3out_name", "name"]
        ),  # Not required for querying all objects
        domain=dict(type="str", aliases=["ext_routed_domain_name", "routed_domain"]),
        vrf=dict(type="str", aliases=["vrf_name"]),
        description=dict(type="str", aliases=["descr"]),
        route_control=dict(
            type="list",
            choices=["export", "import"],
            aliases=["route_control_enforcement"],
        ),
        dscp=dict(
            type="str",
            choices=[
                "AF11",
                "AF12",
                "AF13",
                "AF21",
                "AF22",
                "AF23",
                "AF31",
                "AF32",
                "AF33",
                "AF41",
                "AF42",
                "AF43",
                "CS0",
                "CS1",
                "CS2",
                "CS3",
                "CS4",
                "CS5",
                "CS6",
                "CS7",
                "EF",
                "VA",
                "unspecified",
            ],
            aliases=["target"],
        ),
        l3protocol=dict(type="list", choices=["bgp", "eigrp", "ospf", "pim", "static"]),
        asn=dict(type="int", aliases=["as_number"]),
        state=dict(
            type="str", default="present", choices=["absent", "present", "query"]
        ),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_if=[
            ["state", "absent", ["l3out", "tenant"]],
            ["state", "present", ["l3out", "tenant", "domain", "vrf"]],
        ],
    )

    aci = ACIModule(module)

    l3out = module.params["l3out"]
    domain = module.params["domain"]
    dscp = module.params["dscp"]
    description = module.params["description"]
    enforceRtctrl = module.params["route_control"]
    vrf = module.params["vrf"]
    l3protocol = module.params["l3protocol"]
    asn = module.params["asn"]
    state = module.params["state"]
    tenant = module.params["tenant"]

    if l3protocol:
        if "eigrp" in l3protocol and asn is None:
            module.fail_json(
                msg="Parameter 'asn' is required when l3protocol is 'eigrp'"
            )
        if "eigrp" not in l3protocol and asn is not None:
            module.warn(
                "Parameter 'asn' is only applicable when l3protocol is 'eigrp'. The ASN will be ignored"
            )

    enforce_ctrl = ""
    if enforceRtctrl is not None:
        if len(enforceRtctrl) == 1 and enforceRtctrl[0] == "import":
            aci.fail_json(
                "The route_control parameter is invalid: allowed options are export or import,export only"
            )
        elif len(enforceRtctrl) == 1 and enforceRtctrl[0] == "export":
            enforce_ctrl = "export"
        else:
            enforce_ctrl = "export,import"
    child_classes = [
        "l3extRsL3DomAtt",
        "l3extRsEctx",
        "bgpExtP",
        "ospfExtP",
        "eigrpExtP",
        "pimExtP",
    ]

    aci.construct_url(
        root_class=dict(
            aci_class="fvTenant",
            aci_rn="tn-{0}".format(tenant),
            module_object=tenant,
            target_filter={"name": tenant},
        ),
        subclass_1=dict(
            aci_class="l3extOut",
            aci_rn="out-{0}".format(l3out),
            module_object=l3out,
            target_filter={"name": l3out},
        ),
        child_classes=child_classes,
    )

    aci.get_existing()

    child_configs = [
        dict(l3extRsL3DomAtt=dict(attributes=dict(tDn="uni/l3dom-{0}".format(domain)))),
        dict(l3extRsEctx=dict(attributes=dict(tnFvCtxName=vrf))),
    ]
    if l3protocol is not None:
        for protocol in l3protocol:
            if protocol == "bgp":
                child_configs.append(
                    dict(bgpExtP=dict(attributes=dict(descr="", nameAlias="")))
                )
            elif protocol == "eigrp":
                child_configs.append(
                    dict(
                        eigrpExtP=dict(attributes=dict(descr="", nameAlias="", asn=asn))
                    )
                )
            elif protocol == "ospf":
                child_configs.append(
                    dict(ospfExtP=dict(attributes=dict(descr="", nameAlias="")))
                )
            elif protocol == "pim":
                child_configs.append(
                    dict(pimExtP=dict(attributes=dict(descr="", nameAlias="")))
                )

    if state == "present":
        aci.payload(
            aci_class="l3extOut",
            class_config=dict(
                name=l3out,
                descr=description,
                dn="uni/tn-{0}/out-{1}".format(tenant, l3out),
                enforceRtctrl=enforce_ctrl,
                targetDscp=dscp,
            ),
            child_configs=child_configs,
        )

        aci.get_diff(aci_class="l3extOut")

        aci.post_config()

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

    aci.exit_json()