aws-cloudformation / aws-cloudformation-resource-providers-stepfunctions

The CloudFormation Resource Provider Package For AWS Step Functions
https://aws.amazon.com/step-functions/
Apache License 2.0
6 stars 4 forks source link

(StateMachine): Support null ResultPath, InputPath, and OutputPath when using the "Definition" property #41

Open wong-a opened 1 year ago

wong-a commented 1 year ago

Description

It is not possible to set ResultPath, InputPath, and OutputPath to null when using the Definition property in AWS::StepFunctions::StateMachine. CloudFormation does not accept null property values.

There is a AWS::NoValue pseudo-parameter, but that just omits the property instead of serializing it to "ResultPath": null in the JSON string. This isn't the desired behaviour because ResultPath, InputPath, and OutputPath have a default value of $ when unspecified in the state machine definition.

Current workarounds:

Use case

The usage of null values is described below from the Amazon States Language specification. As a CloudFormation user, I should be able to set when using the Definition property to declare my ASL definition as a JSON/YAML object:

If the value of InputPath is null, that means that the raw input is discarded, and the effective input for the state is an empty JSON object, {}. Note that having a value of null is different from the "InputPath" field being absent.

If the value of ResultPath is null, that means that the state’s result is discarded and its raw input becomes its result.

If the value of OutputPath is null, that means the input and result are discarded, and the effective output from the state is an empty JSON object, {}.

Defaults

Each of InputPath, Parameters, ResultSelector, ResultPath, and OutputPath are optional. The default value of InputPath is "$", so by default the effective input is just the raw input. The default value of ResultPath is "$", so by default a state’s result overwrites and replaces the input. The default value of OutputPath is "$", so by default a state’s effective output is the result of processing ResultPath.

Parameters and ResultSelector have no default value. If absent, they have no effect on their input.

Therefore, if none of InputPath, Parameters, ResultSelector, ResultPath, or OutputPath are supplied, a state consumes the raw input as provided and passes its result to the next state.

Proposed Solution

Support a reserved string "NULL" or "DISCARD" for InputPath, OutputPath, and ResultPath which the resource handler translates into an explicit null property when serializing the Definition object into a JSON string before the Create/UpdateStateMachine request.

Example

Using the following template:

MyStateMachine:
  Type: AWS::StepFunctions::StateMachine
  Properties:
    RoleArn: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/myIamRole
    Definition:
      StartAt: PassState
      States:
        PassState:
          Type: Pass
          Result: Result
          InputPath: "NULL"
          ResultPath: "NULL"
          OutputPath: "NULL"
          End: true

Should yield this ASL definition in the created StateMachine:

{
  "StartAt": "PassState",
  "States": {
    "PassState": {
      "Type": "Pass",
      "Result": "Result",
      "InputPath": null,
      "ResultPath": null,
      "OutputPath": null,
      "End": true
    }
  }
}

Other Information

The special string we use must be a reserved keyword that would fail in the Create/UpdateStateMachine API today. Per ASL spec, the value of ResultPath, InputPath, and OutputPath must be null or valid Paths, so there is a lot of flexibility as long as it's not a JSONPath. We just need to be wary of future changes to ASL where these fields could accept a non-Path value.

Related:

Acknowledgements

evscott commented 1 year ago

An unfortunate workaround, but I think it is reasonable given the circumstances. Thanks for documenting the issue and writing up a potential solution.

pplu commented 1 year ago

I have hit the same bug. Has a workaround been implemented?

gabemastey commented 10 months ago

+1 to the proposal. Would be really good to get this fix working.