0
votes

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
A potentially relevant discussion threadHarrison Totty

1 Answers

1
votes

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" }.