Search code examples
amazon-web-servicesaws-step-functions

How to make a AWS step function wait a configurable amount of time?


This is a snippet of the CloudFormation for my state machine that is supposed to wait a configurable amount of time before invoking a lambda function.

  StepFunctionsStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: userNotificationPipeline
      DefinitionString: !Sub |
        {
          "Comment": "A description of my state machine",
          "StartAt": "Wait",
          "States": {
            "Wait": {
              "Type": "Wait",
              "Seconds": $.Input.Timer,
              "Next": "Lambda Invoke"
            },
            "Lambda Invoke": {
              "Type": "Task",
              "Resource": "arn:aws:states:::lambda:invoke",
              "OutputPath": "$.Payload",
              "Parameters": {
                "FunctionName": "endUserNotificationReminder",
                "Payload.$": "$"
              },
              "End": true
            }
          }
        }

When building, I run into this error. It looks like it doesn't like the $.Input.Timer because $ is not a JSON token:

1 validation error detected: Value 'Invalid State Machine Definition: 'INVALID_JSON_DESCRIPTION: Unrecognized token '$': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (String)"{ "Comment": "A description of my state machine", "StartAt": "Wait", "States": { "Wait": { "Type": "Wait", "Seconds": $.Input.Timer, "Next": "Lambda Invoke" }, "Lambda Invoke": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "OutputPath": "$.Payload", "Parameters": { "FunctionName": "endUserNotificationReminder", "Payload.$": "$" }, "End": true } } } "; line: 7, column: 19] at [Source: (String)"{ "Comment": "A description of my state machine", "StartAt": "Wait", "States": { "Wait": { "Type": "Wait", "Seconds": $.Input.Timer, "Next": "Lambda Invoke" }, "Lambda Invoke": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "OutputPath": "$.Payload", "Parameters": { "FunctionName": "endUserNotificationReminder", "Payload.$": "$" }, "End": true } } } "; line: 7, column: 19]' (Service: AWSStepFunctions; Status Code: 400; Error Code: InvalidDefinition; Request ID: c561eced-0644-462a-a88a-0457b82ec23b; Proxy: null)' at 'statusMessage' failed to satisfy constraint: Member must have length less than or equal to 1024

I came across this question which had a similar problem, and the solution was to put quotes around the $.Input.Timer, but that didn't work for me because the Wait state expects the value of "Seconds" to be an integer, not a string:

Resource handler returned message: "Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: Expected value of type Integer at /States/Wait/Seconds' (Service: AWSStepFunctions; Status Code: 400; Error Code: InvalidDefinition; Request ID: fe1a8fb2-dcc1-4a35-ab66-441753e001c1; Proxy: null)" (RequestToken: a380c94f-153c-09ba-9bbb-583a83bf2019, HandlerErrorCode: InvalidRequest)

What do I need to do to make $.Input.Timer get past the JSON parser and be treated as an integer?


Solution

  • The value of Seconds must be a positive integer. To specify a value from the state input with JSONPath, use SecondsPath instead.

    "Wait": {
      "Type": "Wait",
      "SecondsPath": "$.Input.Timer",
      "Next": "Lambda Invoke"
    }
    

    https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-wait-state.html