Skip to main content
AWS Step Functions — Are Active Executions Affected When Your State Machine Gets Updated?

AWS Step Functions — Are Active Executions Affected When Your State Machine Gets Updated?

·4 mins· loading ·
AWS Lambda Serverless Step Functions CDK
Pubudu Jayawardana
Author
Pubudu Jayawardana
Cloud Engineer, AWS Community Builder

Intro
#

AWS Step Functions is a Serverless orchestration service that helps to build a workflow with various steps that connect different AWS services. These steps are defined in State Machine, which will be implemented in Amazon States Language (ASL).

There are two types of workflows in Step Functions:

  1. Express flow
  2. Standard flow

Among many differences, Express flow can only run up to five minutes and Standard flow can run up to one year.

Since even five minutes is a long time, there is a possibility of having an active execution when the state machine is updated. In this article, I am going to discuss how such active executions are affected when the State Machine is updated and how to handle those scenarios.

Let’s assume we have a simple state machine with two Lambda functions as follows. There is a “Wait” state with a three-minute wait time in between Lambda calls.

Image: Two Lambda Functions with Wait State
Image: Two Lambda Functions with Wait State

Scenario 1
#

Here, we will run the above state machine, and while there is an active execution, we will update the state machine by adding a third Lambda function after the second Lambda function.

Image: State Machine updated with 3rd Lamba Function
Image: State Machine updated with 3rd Lamba Function

The result is that the active execution is not affected.

The reason is when a new execution initialised, the Step Function keeps a ‘snapshot’ of the State Machine and any updates to the State Machine is not affect this ‘snapshot.’

Scenario 2
#

Here, we will run the state machine in Fig 1, and this time we will keep the State Machine as it is, but, we will update the second Lambda function code.

The result is that the active execution is affected.

The reason is although Step Function keeps a ‘snapshot’ of the state machine at the start of the execution, the Lambda functions in the state machine are referenced with their ARNs. This is the latest version of Lambda. So, if the Lambda functions are updated, it affects the running execution since it always refers to the latest version of Lambda.

How To Prevent Modifications To Active Executions When Lambda Functions Update?
#

There is a simple solution for this: use Lambda versions.

On deployment, create a Lambda version and in the state machine, refer to the Lambda function with the version in the ARN.

Example: arn:aws:lambda:[region]:[accountId]:function:[functionName]:[Version]

An example of this implementation is this CDK code snippet.

Previously (without Lambda versions):

const lambdaFunctionOne = new nodejs_lambda.NodejsFunction(this, "LambdaFunctionOne", {
      runtime: lambda.Runtime.NODEJS_14_X,
      entry: path.join(__dirname, `/../lambda/FunctionOne/index.ts`),
      handler: "handler",
      timeout: Duration.minutes(10),
    });

    const waitForXMinutes = new sfn.Wait(this, 'Wait', {
      time: sfn.WaitTime.duration(Duration.minutes(3)),
    });

    const lambdaFunctionTwo = new nodejs_lambda.NodejsFunction(this, "LambdaFunctionTwo", {
      runtime: lambda.Runtime.NODEJS_14_X,
      entry: path.join(__dirname, `/../lambda/FunctionTwo/index.ts`),
      handler: "handler",
      timeout: Duration.minutes(10),
    });

    const stateMachine = new sfn.StateMachine(this, 'SfTestStateMachine', {
      definition: new tasks.LambdaInvoke(this, 'TriggerLambdaFunctionOne', {
        lambdaFunction: lambdaFunctionOne
      })
      .next(waitForXMinutes)
      .next(
        new tasks.LambdaInvoke(this, 'TriggerLambdaFunctionTwo', {
          lambdaFunction: lambdaFunctionTwo
        })
      )
    });

Now (with Lambda versions):

const lambdaFunctionOne = new nodejs_lambda.NodejsFunction(this, "LambdaFunctionOne", {
      runtime: lambda.Runtime.NODEJS_14_X,
      entry: path.join(__dirname, `/../lambda/FunctionOne/index.ts`),
      handler: "handler",
      timeout: Duration.minutes(10),
    });

    const waitForXMinutes = new sfn.Wait(this, 'Wait', {
      time: sfn.WaitTime.duration(Duration.minutes(3)),
    });

    const lambdaFunctionTwo = new nodejs_lambda.NodejsFunction(this, "LambdaFunctionTwo", {
      runtime: lambda.Runtime.NODEJS_14_X,
      entry: path.join(__dirname, `/../lambda/FunctionTwo/index.ts`),
      handler: "handler",
      timeout: Duration.minutes(10),
    });

    const stateMachine = new sfn.StateMachine(this, 'SfTestStateMachine', {
      definition: new tasks.LambdaInvoke(this, 'TriggerLambdaFunctionOne', {
        lambdaFunction: new lambda.Version(this, 'LambdaFunctionOneVersion', {
          lambda: lambdaFunctionOne,
        })
      })
      .next(waitForXMinutes)
      .next(
        new tasks.LambdaInvoke(this, 'TriggerLambdaFunctionTwo', {
          lambdaFunction: new lambda.Version(this, 'LambdaFunctionTwoVersion', {
            lambda: lambdaFunctionTwo,
          })
        })
      )
    });

Conclusion
#

When using Lambda functions within Step Functions, use the Lambda function versions to make sure any active executions are not affected by Lambda updates.

In contrast, if you need any active executions to be updated with the latest Lambda code, do not use Lambda function versions.

Resources
#

  1. AWS Step Functions Express vs Standard workflows: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html

  2. Documentation — Amazon State Language: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html

  3. Documentation — State Machine: https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-state-machine-structure.html


Please feel free to try this and share your experience with me.

Keep building! Keep sharing!

[Header image by davide ragusa on Unsplash]

Related

Simple Leave Management System with AWS Serverless
·5 mins· loading
AWS Lambda Serverless Step Functions DynamoDB SES
This is how I built a simple leave management system using AWS Serverless services
How to create a simple OTP service with AWS Serverless services
·4 mins· loading
AWS Serverless SES Lambda DynamoDB APIGateway
This post describes how to implement a simple One Time Password (OTP) system with AWS Serverless services
How I created a Photo Booth with AWS Serverless
·4 mins· loading
AWS Serverless Step Functions Lambda SES S3
This explains how I created a simple photo booth with AWS Serverless services