AWS StepFunctions - SageMaker's InvokeEndpoint block throws "validation error" when fetching parameters for itself inside iterator of Map block

0

I have a state-machine workflow with 3 following states:

screenshot-of-my-workflow

  1. A 'Pass' block that adds a list of strings(SageMaker endpoint names) to the original input. (this 'Pass' will be replaced by a call to DynamoDB to fetch list in future.)
  2. Use map to call SageMaker endpoints dictated by the array(or list) from above result.
  3. Send the result of above 'Map' to a Lambda function and exit the workflow.

Here's the entire workflow in .asl.json, inspired from this aws blog.

{
  "Comment": "A description of my state machine",
  "StartAt": "Pass",
  "States": {
    "Pass": {
      "Type": "Pass",
      "Next": "InvokeEndpoints",
      "Result": {
        "Endpoints": [
          "sagemaker-endpoint-1",
          "sagemaker-endpoint-2",
          "sagemaker-endpoint-3"
        ]
      },
      "ResultPath": "$.EndpointList"
    },
    "InvokeEndpoints": {
      "Type": "Map",
      "Next": "Post-Processor Lambda",
      "Iterator": {
        "StartAt": "InvokeEndpoint",
        "States": {
          "InvokeEndpoint": {
            "Type": "Task",
            "End": true,
            "Parameters": {
              "Body": "$.InvocationBody",
              "EndpointName": "$.EndpointName"
            },
            "Resource": "arn:aws:states:::aws-sdk:sagemakerruntime:invokeEndpoint",
            "ResultPath": "$.InvocationResult"
          }
        }
      },
      "ItemsPath": "$.EndpointList.Endpoints",
      "MaxConcurrency": 300,
      "Parameters": {
        "InvocationBody.$": "$.body.InputData",
        "EndpointName.$": "$$.Map.Item.Value"
      },
      "ResultPath": "$.InvocationResults"
    },
    "Post-Processor Lambda": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "Payload.$": "$",
        "FunctionName": "arn:aws:lambda:<my-region>:<my-account-id>:function:<my-lambda-function-name>:$LATEST"
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 6,
          "BackoffRate": 2
        }
      ],
      "End": true
    }
  }
}

As can be seen in the workflow, I am iterating over the list from the previous 'Pass' block and mapping those to iterate inside 'Map' block and trying to access the Parameters of 'Map' block inside each iteration. Iteration works fine with number of iterators, but I can't access the Parameters inside the iteration. I get this error:

{
  "resourceType": "aws-sdk:sagemakerruntime",
  "resource": "invokeEndpoint",
  "error": "SageMakerRuntime.ValidationErrorException",
  "cause": "1 validation error detected: Value '$.EndpointName' at 'endpointName' failed to satisfy constraint: Member must satisfy regular expression pattern: ^[a-zA-Z0-9](-*[a-zA-Z0-9])* (Service: SageMakerRuntime, Status Code: 400, Request ID: ed5cad0c-28d9-4913-853b-e5f9ac924444)"
}

So, I presume the error is because "$.EndpointName" is not being filled with the relevant value. How do I avoid this.

But, when I open the failed execution and check the InvokeEndpoint block from graph-inspector, input to that is what I expected and above JSON-Paths to fetch the parameters should work, but they don't.
screenshot-of-graph-inspector

What's causing the error and How do I fix this?

1 Answer
1
Accepted Answer

In general (as mentioned here in the parameters doc), you also need to end the parameter name with .$ when using a JSON Path.

It looks like you're doing that some places in your sample JSON (e.g. "InvocationBody.$": "$.body.InputData"), but not in others ("EndpointName": "$.EndpointName"), so I think the reason you're seeing the validation error here is that Step Functions is trying to interpret $.EndpointName as literally the name of the endpoint (which doesn't satisfy ^[a-zA-Z0-9](-*[a-zA-Z0-9])*!)

So suggest you change to EndpointName.$ and Body.$ in your InvokeEndpoint parameters

AWS
EXPERT
Alex_T
answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions