# Buggy code
def create_or_update_elb_listeners(connection, module, elb):
    """Create or update ELB listeners. Return true if changed, else false"""

    listener_changed = False
    # Ensure listeners are using Target Group ARN not name
    listeners = ensure_listeners_default_action_has_arn(
        connection, module, module.params.get("listeners")
    )
    purge_listeners = module.params.get("purge_listeners")

    # Does the ELB have any listeners exist?
    current_listeners = get_elb_listeners(connection, module, elb["LoadBalancerArn"])

    listeners_to_add, listeners_to_modify, listeners_to_delete = compare_listeners(
        connection, module, current_listeners, deepcopy(listeners), purge_listeners
    )

    # Add listeners
    for listener_to_add in listeners_to_add:
        try:
            listener_to_add["LoadBalancerArn"] = elb["LoadBalancerArn"]
            connection.create_listener(**listener_to_add)
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # Modify listeners
    for listener_to_modify in listeners_to_modify:
        try:
            connection.modify_listener(**listener_to_modify)
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # Delete listeners
    for listener_to_delete in listeners_to_delete:
        try:
            connection.delete_listener(ListenerArn=listener_to_delete)
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # For each listener, check rules
    for listener in listeners:
        if "Rules" in listener:
            # Ensure rules are using Target Group ARN not name
            listener["Rules"] = ensure_rules_action_has_arn(
                connection, module, listener["Rules"]
            )
            rules_to_add, rules_to_modify, rules_to_delete = compare_rules(
                connection, module, current_listeners, listener
            )

            # Get listener based on port so we can use ARN
            looked_up_listener = get_listener(
                connection, module, elb["LoadBalancerArn"], listener["Port"]
            )

            # Add rules
            for rule in rules_to_add:
                try:
                    rule["ListenerArn"] = looked_up_listener["ListenerArn"]
                    rule["Priority"] = int(rule["Priority"])
                    connection.create_rule(**rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

            # Modify rules
            for rule in rules_to_modify:
                try:
                    del rule["Priority"]
                    connection.modify_rule(**rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

            # Delete rules
            for rule in rules_to_delete:
                try:
                    connection.delete_rule(RuleArn=rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

    return listener_changed


# Traceback (ParamValidationError)
Unknown parameter in input: "Rules", must be one of: LoadBalancerArn, Protocol, Port, SslPolicy, Certificates, DefaultActions
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_LtFMN2/ansible_module_elb_application_lb.py\", line 1011, in <module>\n    main()\n  File \"/tmp/ans
ible_LtFMN2/ansible_module_elb_application_lb.py\", line 1006, in main\n    create_or_update_elb(connection, connection_ec2, module)\n  File \"/tmp/ansible_LtFMN2/ansible_module_elb_application_lb.py\", line 901, in create_or_update_elb\n
listener_changed = create_or_update_elb_listeners(connection, module, elb)\n  File \"/tmp/ansible_LtFMN2/ansible_module_elb_application_lb.py\", line 722, in create_or_update_elb_listeners\n    connection.create_listener(**listener_to_add)\n
File \"/usr/local/lib/python2.7/dist-packages/botocore/client.py\", line 310, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/botocore/client.py\", line 573, in _make_api_
call\n    api_params, operation_model, context=request_context)\n  File \"/usr/local/lib/python2.7/dist-packages/botocore/client.py\", line 628, in _convert_to_request_dict\n    api_params, operation_model)\n  File \"/usr/local/lib/python2.7/
dist-packages/botocore/validate.py\", line 291, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\nbotocore.exceptions.ParamValidationError: Parameter validation failed:\nUnknown parameter in input: \"Ru
les\", must be one of: LoadBalancerArn, Protocol, Port, SslPolicy, Certificates, DefaultActions\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}

# Fixed code
def create_or_update_elb_listeners(connection, module, elb):
    """Create or update ELB listeners. Return true if changed, else false"""

    listener_changed = False
    # Ensure listeners are using Target Group ARN not name
    listeners = ensure_listeners_default_action_has_arn(
        connection, module, module.params.get("listeners")
    )
    purge_listeners = module.params.get("purge_listeners")

    # Does the ELB have any listeners exist?
    current_listeners = get_elb_listeners(connection, module, elb["LoadBalancerArn"])

    listeners_to_add, listeners_to_modify, listeners_to_delete = compare_listeners(
        connection, module, current_listeners, deepcopy(listeners), purge_listeners
    )

    # Add listeners
    for listener_to_add in listeners_to_add:
        try:
            listener_to_add["LoadBalancerArn"] = elb["LoadBalancerArn"]
            # Rules is not a valid parameter for create_listener
            listener_to_add.pop("Rules")
            response = connection.create_listener(**listener_to_add)
            # Add the new listener
            current_listeners.append(response["Listeners"][0])
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # Modify listeners
    for listener_to_modify in listeners_to_modify:
        try:
            # Rules is not a valid parameter for modify_listener
            listener_to_modify.pop("Rules")
            connection.modify_listener(**listener_to_modify)
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # Delete listeners
    for listener_to_delete in listeners_to_delete:
        try:
            connection.delete_listener(ListenerArn=listener_to_delete)
            listener_changed = True
        except ClientError as e:
            module.fail_json(
                msg=e.message,
                exception=traceback.format_exc(),
                **camel_dict_to_snake_dict(e.response),
            )

    # For each listener, check rules
    for listener in deepcopy(listeners):
        if "Rules" in listener:
            # Ensure rules are using Target Group ARN not name
            listener["Rules"] = ensure_rules_action_has_arn(
                connection, module, listener["Rules"]
            )
            rules_to_add, rules_to_modify, rules_to_delete = compare_rules(
                connection, module, current_listeners, listener
            )

            # Get listener based on port so we can use ARN
            looked_up_listener = get_listener(
                connection, module, elb["LoadBalancerArn"], listener["Port"]
            )

            # Add rules
            for rule in rules_to_add:
                try:
                    rule["ListenerArn"] = looked_up_listener["ListenerArn"]
                    rule["Priority"] = int(rule["Priority"])
                    connection.create_rule(**rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

            # Modify rules
            for rule in rules_to_modify:
                try:
                    del rule["Priority"]
                    connection.modify_rule(**rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

            # Delete rules
            for rule in rules_to_delete:
                try:
                    connection.delete_rule(RuleArn=rule)
                    listener_changed = True
                except ClientError as e:
                    module.fail_json(
                        msg=e.message,
                        exception=traceback.format_exc(),
                        **camel_dict_to_snake_dict(e.response),
                    )

    return listener_changed