# Buggy code
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            iam_type=dict(required=True, choices=["user", "group", "role"]),
            state=dict(default="present", choices=["present", "absent"]),
            iam_name=dict(default=None, required=False),
            policy_name=dict(required=True),
            policy_document=dict(default=None, required=False),
            policy_json=dict(type="json", default=None, required=False),
            skip_duplicates=dict(type="bool", default=True, required=False),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
    )

    if not HAS_BOTO:
        module.fail_json(msg="boto required for this module")

    iam_type = module.params.get("iam_type").lower()
    state = module.params.get("state")
    name = module.params.get("iam_name")
    policy_name = module.params.get("policy_name")
    skip = module.params.get("skip_duplicates")

    policy_document = module.params.get("policy_document")
    if policy_document is not None and module.params.get("policy_json") is not None:
        module.fail_json(
            msg='Only one of "policy_document" or "policy_json" may be set'
        )

    if policy_document is not None:
        try:
            with open(policy_document, "r") as json_data:
                pdoc = json.dumps(json.load(json_data))
                json_data.close()
        except IOError as e:
            if e.errno == 2:
                module.fail_json(
                    msg="policy_document {0:!r} does not exist".format(policy_document)
                )
            else:
                raise
    elif module.params.get("policy_json") is not None:
        pdoc = module.params.get("policy_json")
        # if its a string, assume it is already JSON
        if not isinstance(pdoc, string_types):
            try:
                pdoc = json.dumps(pdoc)
            except Exception as e:
                module.fail_json(
                    msg="Failed to convert the policy into valid JSON: %s" % str(e)
                )
    else:
        pdoc = None

    region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module)

    try:
        if region:
            iam = connect_to_aws(boto.iam, region, **aws_connect_kwargs)
        else:
            iam = boto.iam.connection.IAMConnection(**aws_connect_kwargs)
    except boto.exception.NoAuthHandlerFound as e:
        module.fail_json(msg=str(e))

    changed = False

    if iam_type == "user":
        changed, user_name, current_policies = user_action(
            module, iam, name, policy_name, skip, pdoc, state
        )
        module.exit_json(changed=changed, user_name=name, policies=current_policies)
    elif iam_type == "role":
        changed, role_name, current_policies = role_action(
            module, iam, name, policy_name, skip, pdoc, state
        )
        module.exit_json(changed=changed, role_name=name, policies=current_policies)
    elif iam_type == "group":
        changed, group_name, current_policies, msg = group_action(
            module, iam, name, policy_name, skip, pdoc, state
        )
        module.exit_json(
            changed=changed, group_name=name, policies=current_policies, msg=msg
        )


# Traceback (nansible.module_utils.ec2.AnsibleAWSError)
{
"exception": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 114, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 106, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 49, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/__main__.py\", line 351, in <module>\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/__main__.py\", line 325, in main\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/ansible_iam_policy_payload.zip/ansible/module_utils/ec2.py\", line 340, in connect_to_aws\nansible.module_utils.ec2.AnsibleAWSError: Region us-gov-east-1 does not seem to be available for aws module boto.iam. If the region definitely exists, you may need to upgrade boto or extend with endpoints_path\n",
"_ansible_no_log": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 114, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 106, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1572882827.2-191594499800419/AnsiballZ_iam_policy.py\", line 49, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/__main__.py\", line 351, in <module>\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/__main__.py\", line 325, in main\n  File \"/tmp/ansible_iam_policy_payload_1NDwn0/ansible_iam_policy_payload.zip/ansible/module_utils/ec2.py\", line 340, in connect_to_aws\nansible.module_utils.ec2.AnsibleAWSError: Region us-gov-east-1 does not seem to be available for aws module boto.iam. If the region definitely exists, you may need to upgrade boto or extend with endpoints_path\n",
"changed": false,
"module_stdout": "",
"rc": 1,
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}

# Fixed code
def main():
    argument_spec = dict(
        iam_type=dict(required=True, choices=["user", "group", "role"]),
        state=dict(default="present", choices=["present", "absent"]),
        iam_name=dict(default=None, required=False),
        policy_name=dict(required=True),
        policy_document=dict(default=None, required=False),
        policy_json=dict(type="json", default=None, required=False),
        skip_duplicates=dict(type="bool", default=None, required=False),
    )
    mutually_exclusive = [["policy_document", "policy_json"]]

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        mutually_exclusive=mutually_exclusive,
        supports_check_mode=True,
    )

    skip_duplicates = module.params.get("skip_duplicates")

    if skip_duplicates is None:
        module.deprecate(
            "The skip_duplicates behaviour has caused confusion and"
            " will be disabled by default in Ansible 2.14",
            version="2.14",
        )
        skip_duplicates = True

    if module.params.get("policy_document"):
        module.deprecate(
            "The policy_document option has been deprecated and"
            " will be removed in Ansible 2.14",
            version="2.14",
        )

    args = dict(
        client=module.client("iam"),
        name=module.params.get("iam_name"),
        policy_name=module.params.get("policy_name"),
        policy_document=module.params.get("policy_document"),
        policy_json=module.params.get("policy_json"),
        skip_duplicates=skip_duplicates,
        state=module.params.get("state"),
        check_mode=module.check_mode,
    )
    iam_type = module.params.get("iam_type")

    try:
        if iam_type == "user":
            policy = UserPolicy(**args)
        elif iam_type == "role":
            policy = RolePolicy(**args)
        elif iam_type == "group":
            policy = GroupPolicy(**args)

        module.exit_json(**(policy.run()))
    except (BotoCoreError, ClientError) as e:
        module.fail_json_aws(e)
    except PolicyError as e:
        module.fail_json(msg=str(e))