# Buggy code
def main():
    """
    Main entry point.

    :return dict: ansible facts
    """
    argument_spec = dict(
        function_name=dict(required=False, default=None, aliases=["function", "name"]),
        query=dict(
            required=False,
            choices=["aliases", "all", "config", "mappings", "policy", "versions"],
            default="all",
        ),
        event_source_arn=dict(required=False, default=None),
    )

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        mutually_exclusive=[],
        required_together=[],
    )

    # validate function_name if present
    function_name = module.params["function_name"]
    if function_name:
        if not re.search(r"^[\w\-:]+$", function_name):
            module.fail_json(
                msg="Function name {0} is invalid. Names must contain only alphanumeric characters and hyphens.".format(
                    function_name
                )
            )
        if len(function_name) > 64:
            module.fail_json(
                msg='Function name "{0}" exceeds 64 character limit'.format(
                    function_name
                )
            )

    try:
        region, endpoint, aws_connect_kwargs = get_aws_connection_info(
            module, boto3=True
        )
        aws_connect_kwargs.update(
            dict(
                region=region, endpoint=endpoint, conn_type="client", resource="lambda"
            )
        )
        client = boto3_conn(module, **aws_connect_kwargs)
    except ClientError as e:
        module.fail_json_aws(e, "trying to set up boto connection")

    this_module = sys.modules[__name__]

    invocations = dict(
        aliases="alias_details",
        all="all_details",
        config="config_details",
        mappings="mapping_details",
        policy="policy_details",
        versions="version_details",
    )

    this_module_function = getattr(this_module, invocations[module.params["query"]])
    all_facts = fix_return(this_module_function(client, module))

    results = dict(function=all_facts, changed=False)

    if module.check_mode:
        results["msg"] = "Check mode set but ignored for fact gathering only."

    module.exit_json(**results)


# Traceback (AttributeError)
ansible-playbook 2.9.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/ubuntu/.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.15+ (default, Oct  7 2019, 17:39:04) [GCC 7.4.0]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

Loading callback plugin default of type stdout, v2.0 from /usr/lib/python2.7/dist-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: main.yaml ***************************************************************************************************************************************************************************************************************
Positional arguments: main.yaml
become_method: sudo
inventory: (u'/etc/ansible/hosts',)
forks: 5
tags: (u'all',)
extra_vars: (u'envtag=dev',)
verbosity: 4
ssh_common_args: -o StrictHostKeyChecking=no
connection: smart
timeout: 10
1 plays in main.yaml

PLAY [Setup EC2 Keypair] **********************************************************************************************************************************************************************************************************
META: ran handlers

TASK [Get Lambda] *****************************************************************************************************************************************************************************************************************
task path: /home/ubuntu/environment/ConnectEventStream/ansible/main.yaml:17
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ubuntu
<127.0.0.1> EXEC /bin/sh -c 'echo ~ubuntu &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799 `" &amp;&amp; echo ansible-tmp-1573016645.99-133788815155799="` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799 `" ) &amp;&amp; sleep 0'
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/commands/command.py
<127.0.0.1> PUT /home/ubuntu/.ansible/tmp/ansible-local-27933Azyogt/tmp5CUgJa TO /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799/AnsiballZ_command.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799/ /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799/AnsiballZ_command.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799/AnsiballZ_command.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/ubuntu/.ansible/tmp/ansible-tmp-1573016645.99-133788815155799/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
changed: [localhost] => {
"changed": true,
"cmd": "aws lambda get-function --function-name \"ConnectTraceRecordsStream\" --region \"ap-southeast-2\"",
"delta": "0:00:01.698189",
"end": "2019-11-06 05:04:07.964856",
"invocation": {
"module_args": {
"_raw_params": "aws lambda get-function --function-name \"ConnectTraceRecordsStream\" --region \"ap-southeast-2\"",
... REDACTED...
"stdout_lines": [
"{",
"    \"Configuration\": {",
"        \"FunctionName\": \"ConnectTraceRecordsStream\",",
... REDACTED...
}

TASK [Get Lambda Function Details] ************************************************************************************************************************************************************************************************
task path: /home/ubuntu/environment/ConnectEventStream/ansible/main.yaml:20
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ubuntu
<127.0.0.1> EXEC /bin/sh -c 'echo ~ubuntu &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723 `" &amp;&amp; echo ansible-tmp-1573016648.01-175629843213723="` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723 `" ) &amp;&amp; sleep 0'
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/cloud/amazon/lambda_info.py
<127.0.0.1> PUT /home/ubuntu/.ansible/tmp/ansible-local-27933Azyogt/tmpqUCnmY TO /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/ /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py", line 102, in <module>
_ansiballz_main()
File "/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible.modules.cloud.amazon.lambda_info', init_globals=None, run_name='__main__', alter_sys=False)
File "/usr/lib/python2.7/runpy.py", line 192, in run_module
fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/tmp/ansible_lambda_info_payload_yCkK_u/ansible_lambda_info_payload.zip/ansible/modules/cloud/amazon/lambda_info.py", line 398, in <module>
File "/tmp/ansible_lambda_info_payload_yCkK_u/ansible_lambda_info_payload.zip/ansible/modules/cloud/amazon/lambda_info.py", line 386, in main
AttributeError: 'module' object has no attribute 'all_details'

fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1573016648.01-175629843213723/AnsiballZ_lambda_info.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.cloud.amazon.lambda_info', init_globals=None, run_name='__main__', alter_sys=False)\n  File \"/usr/lib/python2.7/runpy.py\", line 192, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_lambda_info_payload_yCkK_u/ansible_lambda_info_payload.zip/ansible/modules/cloud/amazon/lambda_info.py\", line 398, in <module>\n  File \"/tmp/ansible_lambda_info_payload_yCkK_u/ansible_lambda_info_payload.zip/ansible/modules/cloud/amazon/lambda_info.py\", line 386, in main\nAttributeError: 'module' object has no attribute 'all_details'\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}

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

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! ConnectEventStream@0.8.0 deploy: `cd ansible &amp;&amp; ansible-playbook -e "envtag=dev" main.yaml -vvvv --ssh-common-args='-o StrictHostKeyChecking=no'`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the ConnectEventStream@0.8.0 deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/ubuntu/.npm/_logs/2019-11-06T05_04_08_749Z-debug.log

# Fixed code
def main():
    """
    Main entry point.

    :return dict: ansible facts
    """
    argument_spec = dict(
        function_name=dict(required=False, default=None, aliases=["function", "name"]),
        query=dict(
            required=False,
            choices=["aliases", "all", "config", "mappings", "policy", "versions"],
            default="all",
        ),
        event_source_arn=dict(required=False, default=None),
    )

    module = AnsibleAWSModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        mutually_exclusive=[],
        required_together=[],
    )

    # validate function_name if present
    function_name = module.params["function_name"]
    if function_name:
        if not re.search(r"^[\w\-:]+$", function_name):
            module.fail_json(
                msg="Function name {0} is invalid. Names must contain only alphanumeric characters and hyphens.".format(
                    function_name
                )
            )
        if len(function_name) > 64:
            module.fail_json(
                msg='Function name "{0}" exceeds 64 character limit'.format(
                    function_name
                )
            )

    try:
        region, endpoint, aws_connect_kwargs = get_aws_connection_info(
            module, boto3=True
        )
        aws_connect_kwargs.update(
            dict(
                region=region, endpoint=endpoint, conn_type="client", resource="lambda"
            )
        )
        client = boto3_conn(module, **aws_connect_kwargs)
    except ClientError as e:
        module.fail_json_aws(e, "trying to set up boto connection")

    this_module = sys.modules[__name__]

    invocations = dict(
        aliases="alias_details",
        all="all_details",
        config="config_details",
        mappings="mapping_details",
        policy="policy_details",
        versions="version_details",
    )

    this_module_function = globals()[invocations[module.params["query"]]]
    all_facts = fix_return(this_module_function(client, module))

    results = dict(function=all_facts, changed=False)

    if module.check_mode:
        results["msg"] = "Check mode set but ignored for fact gathering only."

    module.exit_json(**results)