1

My CDK infrastructure (a typescript file) has a lambda that will create a new State Machine when it runs. To do so it needs the Amazon State Langauge JSON representation of the machine I want to create. I have created the State Machine within my AWS infrastructure typescript file, since many of the states reference lambdas or dynamoDB tables within this infrastructure.

My question is, given a CDK State Machine (Here is the CDK documentation for it, also here is the documentation for the Step Function's Chain class which basically represents the ASL JSON in CDK) can you generate the ASL JSON representation? In my case it is so I can pass this ASL JSON into one of my lambda's environments.

Based on the documentation it doesn't seem like this is possible which is weird to me since you can just look on the AWS Console, click on your state machine, then click the "definition" tab and see the ASL JSON. There must be some way to access this within the CDK infrastructure where the state machine is defined and created.

BuenasOlas
  • 13
  • 4

1 Answers1

1

Yes, you can pass the L2 StateMachine's generated JSON definition to a Lambda at synth-time. The definition is exposed on its L1 CfnStateMachine child construct. Use escape hatch syntax to get a reference to the CfnStateMachine. Pass its stringified definition to the Lambda as an environment variable.

// MyStack.ts

const sm = new sfn.StateMachine(this, 'StateMachine', {definition: new sfn.Succeed(this, 'SuccessTask'),});
const cfnSm = sm.node.defaultChild as sfn.CfnStateMachine;  // cast to L1 type

if (!cfnSm.definitionString) throw new Error('CfnStateMachine definitionString must be defined');

new lambda.Function(this, 'MyFunction', {
  // ...
  environment: { SM_DEFINITION: cfnSm.definitionString,},
});

Notes:

  1. Alternatively, Lambda can fetch the definition at run-time using the DescribeStateMachine API
  2. The stringified JSON definition is available post-synth (for testing, etc.) in the synthesised stack template in the cdk.out dir.
fedonev
  • 20,327
  • 2
  • 25
  • 34
  • Wow, this is exactly what I was looking for. I had no idea about the escape hatch syntax. Thank you so much. – BuenasOlas Feb 09 '22 at 06:02
  • As a follow up, do you think there is any way to do this without the state machine at all? For instance, in your example you just had a Succeed State. That state could be linked to some others (or be left alone) to form an instance of a Chain object. Is there any way to go from the Chain object to the definition string without actually instantiating the State machine since, in my case at least, this 1 state machine is basically acting like a model state machine for the lambda that is creating SM's based on it. For me having this model state machine actually deployed would be a waste. – BuenasOlas Feb 09 '22 at 06:07
  • Glad to help. Yes, sounds like you can meet your objective without actually deploying a CDK "template" SM. The [CreateStatementMachine](https://docs.aws.amazon.com/step-functions/latest/apireference/API_CreateStateMachine.html) API, which your Lambdas can call, justs expects a JSON definition. The CDK's `sfn.Choice`, `sfn.Success` and related constructs is a code-first way to create a JSON SM definition. Solving how the Lambda injects new composited states into the template (like the AWS Console does) feels like a non-trivial problem, though. – fedonev Feb 09 '22 at 08:05
  • Got it, thanks again. – BuenasOlas Feb 09 '22 at 21:40