2

I have a state machine which contains the following relevant states:

States:
  'Analyze Report':
    Type: Task
    Resource: 'arn:aws:states:::lambda:invoke'
    Parameters:
      FunctionName: '(redacted)'
    OutputPath: '$.Payload'
    Next: 'Setup Email'
  'Setup Email':
    Type: Pass
    Result:
      recipients: '$.accounts'
      subject: 'some email subject'
      body: 'some email body'
    ResultPath: '$'
    Next: 'Send Email'
  'Send Email':
    Type: Task
    Resource: 'arn:aws:states:::lambda:invoke'
    Parameters:
      FunctionName: '(redacted)'
    OutputPath: '$.Payload'
    Next: '(some downstream task)'

The output of the lambda function associated with the Analyze Report step is of the form:

{
  "accounts": ["foo", "bar", "baz"],
  "error_message": null,
  "success": true
}

The lambda function associated with the Send Email step expects an input of the form:

{
  "recipients": ["foo", "bar", "baz"],
  "subject": "some email subject",
  "body": "some email body"
}

When looking at a test execution of the state function, it seems like the Setup Email step is not successfully interpolating the $.accounts string into the accounts array output from the Analyze Report step. Instead, the Send Email step sees the following input:

{
  "recipients": "$.accounts",
  "subject": "some email subject",
  "body": "some email body"
}

I have tried various combinations of things like setting:

# (within the `Setup Email` step)
Result:
  'recipients.$': '$.accounts'

But it doesn't want to seem to interpolate. The documentation provided by AWS seems a bit lacking in this manner.

TL;DR: How do you effectively "rename" an input parameter (with an array value) using a step function step of type Pass?

1

1 Answer 1

6

You need to use Parameters in your Pass state. Here is an example:

{
  "Comment": "A Hello World example of the Amazon States Language using Pass states",
  "StartAt": "Hello",
  "States": {
    "Hello": {
      "Type": "Pass",
      "Parameters": {
        "newName.$": "$.oldName"
      },
      "Next": "World"
    },
    "World": {
      "Type": "Pass",
      "Result": "World",
      "End": true
    }
  }
}

When I run the above with a payload of { "oldName": "some value" } the input to the second state is { "newName": "some value" }.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! I just stumbled upon this myself and was about to answer, so I can verify that this works!
I had a similar problem, but even after adding {"newName.$" : "$.oldName"} to the Parameters of my Pass state, I got an error saying The JSONPath '$.oldName' specified for the field 'newName.$' could not be found in the input '"{\"oldName\": \"some value\"}"'. In my case, this was because I had done a return json.dumps(payload) in the Python code of my first Lambda. I needed to do return payload instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.