Skip to content

lambda_execute should cope with list as payload (instead of dict) #1082

Open

Description

@mdavis-xyz
SUMMARY

AWS Lambda functions are able to process input arguments which are a list, not a dictionary.

Ansible's execute_lambda is not able to.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

execute_lambda

ANSIBLE VERSION
ansible 2.9.0
  config file = /home/ec2-user/.ansible.cfg
  configured module search path = ['/home/ec2-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ec2-user/.local/lib/python3.6/site-packages/ansible
  executable location = /home/ec2-user/.local/bin/ansible
  python version = 3.6.10 (default, Feb 10 2020, 19:55:14) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]

CONFIGURATION
ANSIBLE_PIPELINING(/home/ec2-user/.ansible.cfg) = True
DEFAULT_LOCAL_TMP(/home/ec2-user/.ansible.cfg) = /dev/shm/ansible/tmp_local/ansible-local-71308po4z6ow
OS / ENVIRONMENT

Amazon Linux

STEPS TO REPRODUCE
---
- hosts: localhost
  connection: local

  vars:
    payload:
     - abc
     - 123
    arn: "arn:aws:lambda:ap-southeast-2:123:function:empty" # TODO: change for your case
    region: "ap-southeast-2"

  tasks:
    - name: invoke using cli
      shell: >
        aws lambda invoke
        --function-name {{ arn }}
        --invocation-type RequestResponse
        --payload '{{ payload | to_json }}'
        /tmp/result
    - name: through Ansible module
      execute_lambda:
        function_arn: "{{ arn }}"
        region: "{{ region }}"
        wait: yes
        tail_log: yes
        payload: "{{ payload }}"
  

Where arn is the arn of a Lambda with body:

def lambda_handler(event, context):
    return event

This example invokes the Lambda from the cli (which works),
then tries to do the same thing from execute_lambda, which doesn't work.

EXPECTED RESULTS

The playbook should run without error

ACTUAL RESULTS
TASK [through Ansible module] **********************************************************************************************************************
custom filter file loaded
fatal: [localhost]: FAILED! => {"changed": false, "msg": "argument payload is of type <class 'list'> and we were unable to convert to dict: <class 'list'> cannot be converted to a dict"}

Activity

  1. mdavis-xyz commented on Jun 27, 2020

    @mdavis-xyz
    ContributorAuthor

    I can't see where the problem is.

    Line 218 should take a list fine. Same with line 173.

    I think the solution is as simple as modifying line 154, where the argument spec is, to allow dicts and lists.

    I'm happy to write this PR myself (change that line, add an integration test, update documentation), as soon as someone answers issue ansible-collections/community.aws#120 .

    Tagging maintainer: @ryansb

  2. mdavis-xyz commented on Jun 30, 2020

    @mdavis-xyz
    ContributorAuthor

    Hmm, it looks like you can tell Ansible that an argument is a dict, or a list, but you can't tell it to accept either.
    Is that correct?

    https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#documentation-fields

  3. mdavis-xyz commented on Jun 30, 2020

    @mdavis-xyz
    ContributorAuthor

    I suppose one workaround would be to add a second argument. So you do either payload: {} or payload_list: []. But that's not ideal.

  4. ansibullbot commented on Aug 19, 2020

    @ansibullbot
  5. goneri commented on Feb 3, 2021

    @goneri
    Member

    Hi @mdavis-xyz,

    I'm not totally sure if we need a new key for that but since you've already done 80% of the job, I suggest you to push a PR for review.

  6. mdavis-xyz commented on Feb 3, 2021

    @mdavis-xyz
    ContributorAuthor

    Adding a new key really doesn't seem like the best solution. In theory Ansible modules can take in any arbitrary json. So it should be possible.

    I've dug deeper. Here's the list of standard Ansible types..
    I suspect that json would work. (Noting that it would end up in the module as a string, not a list/dict. Which is fine because we have to dump the payload to json anyway.) raw would probably work too.

    Which is better: raw or json?

    If neither works, it looks like we can even pass in a callable to do the conversion ourselves.

  7. mdavis-xyz commented on Feb 3, 2021

    @mdavis-xyz
    ContributorAuthor

    This issue has a related example

  8. goneri commented on Feb 4, 2021

    @goneri
    Member
  9. mdavis-xyz commented on Feb 4, 2021

    @mdavis-xyz
    ContributorAuthor

    Looking at this comment I'm leaning more towards json instead of raw. json` will do validation to ensure that the payload can be dumped to json, which is a requirement for this use case, right?

    What type validation do we have to do for raw, other than checking that it can be dumped with json.dumps?

    I'm trying to think about the edge case where someone might want to invoke a Lambda with a payload that is just a string, i.e. json.dumps("{"). Oh well, I guess we can check that with the tests.

  10. changed the title [-]execute_lambda should cope with list as payload (instead of dict)[/-] [+]lambda_execute should cope with list as payload (instead of dict)[/+] on Sep 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions