Cherry
Cherry

Reputation: 33600

How use Fn::Include and Fn::Sub together?

Consider this code:

MyStateMachine:
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
        StateMachineName: MyStateMachine
        DefinitionString:
            Fn::Sub:
                - Fn::Transform:
                     Name: 'AWS::Include'
                     Parameters:
                         Location: s3://my-bucket/my.json
                - { Param1: MyLambda1.Arn, Param2: MyLambda2.Arn }

I got an error:

Template error: One or more Fn::Sub intrinsic functions don't specify expected arguments. Specify a string as first argument, and an optional second argument to specify a mapping of values to replace in the string

It is required that first argument must be a string, but what if state machine has place holder for arn? How to replace them? Any workarounds?

Upvotes: 4

Views: 1435

Answers (1)

Dunedan
Dunedan

Reputation: 8435

Fn::Sub doesn't support Fn::Transform as part of the input. As stated in the documentation:

For the String parameter, you cannot use any functions. You must specify a string value.

One solution would be to include the state machine definition in the CloudFormation template directly, without resorting to Fn::Transform and Fn::Include, which would allow you to use Fn::Sub to replace the placeholders.

Depending on your reasoning behind putting the state machine definition in S3 that might even make sense from an architectural point of view, as you wouldn't need a separate S3 bucket for storing the state machine definition anymore and the definition would be tightly coupled to the CloudFormation stack which (presumably) creates the AWS Lambda functions which are used in the state machine anyway.

I'm afraid that's the only solution possible so far, because Fn::Sub is fairly limited in this regard. Even if you'd have the state machine definition available as string which can be referenced (e.g. as parameter) in your template you could only replace the reference with the state machine definition string, but not anything inside that string.

Upvotes: 2

Related Questions