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

How to Pass a parameter based on value of one of the input parameter in AWS Step Function?


For AWS Step Function, I am trying to pass in new parameter which will be derived from another input parameter. Here is an example:

Input param to Step Function will be:

{
  "abc": <abc_value>
  OR
  "def": <def_value>
}

This should be input params to further steps, if abc is present and value is A:

{
  "abc": "A",
  "def": "X"
}

This should be input params to further steps, if abc is present and value is B:

{
  "abc": "B",
  "def": "Y"
}

I tried to search the solution for it and seems like it can be done with combination of Pass and Choice states like following and couldn't found any other solution:

{
  "StartAt": "InputRouterStep",
  "States": {
    "InputRouterStep": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.abc",
          "IsPresent": true,
          "Next": "DeriveDef"
        }
      ],
      "Default": "MainSteps"
    },
    "DeriveDef": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.abc",
          "StringEquals": "A",
          "Next": "PassDefForA"
        },
        {
          "Variable": "$.abc",
          "StringEquals": "B",
          "Next": "PassDefForB"
        }
      ],
      "Default": "PassDefForA"
    },
    "PassDefForA": {
      "Type": "Pass",
      "Parameters": {
        "abc.$": "$.abc"
        "def": "X"
      },
      "Next": "MainSteps"
    },
    "PassDefForB": {
      "Type": "Pass",
      "Parameters": {
        "abc.$": "$.abc"
        "def": "Y"
      },
      "Next": "MainSteps"
    },
...

Can someone please help me out here to understand if there is any more efficient way to do this? Probably Lambda can be one, but it is very short computation, may be above solution is better?


Solution

  • If I understand correctly, your solution is pretty "efficient" in the sense you won't need to invoke an additional lambda and incur the extra state transitions of doing so.

    From a maintanence standpoint, the following (imho) might be easier to update down the road for future values of $.abc, needing to only the valid values in the ConditionalDefaultForDEF and the corresponding values in the InputRouteStep.

    {
      "StartAt": "ConditionalDefaultForDEF",
      "States": {
        "ConditionalDefaultForDEF": {
          "Type": "Pass",
          "Result": [
            {
              "key": "A",
              "value": "X"
            },
            {
              "key": "B",
              "value": "Y"
            }
          ],
          "ResultPath": "$.abc_mapping",
          "Next": "InputRouterStep"
        },
        "InputRouterStep": {
          "Type": "Choice",
          "Choices": [
            {
              "And": [
                {
                  "Variable": "$.abc",
                  "IsPresent": true
                },
                {
                  "And": [
                    {
                      "Or": [
                        {
                          "Variable": "$.abc",
                          "StringEquals": "A"
                        },
                        {
                          "Variable": "$.abc",
                          "StringEquals": "B"
                        }
                      ]
                    }
                  ]
                }
              ],
              "Next": "PassDef"
            }
          ],
          "Default": "MainSteps"
        },
        "PassDef": {
          "Type": "Pass",
          "InputPath": "$.abc_mapping[?(@.key == $['abc'])].value",
          "Parameters": {
            "def.$": "$[0]"
          },
          "Next": "MainSteps"
        },
        "...": "..."
      }
    }