Invoke AWS Step Function from AWS Lambda using the Serverless Framework

Noah Ispas
3 min readNov 9, 2017

--

In one of my last articles I showed how to chain Lambda Functions which means to invoke one Lambda Function from another one. This time I want to show you how you can invoke a Step Function from a Lambda Function using the Serverless Framework.

A use case for this kind of a setup is if you for example have a Step Function which should be invoked after receiving a request through an AWS API Gateway and want to let’s say validate the requests.

TL;DR

Here you can find a GitHub repository if you want a quick start.

Prerequisites

Follow the instructions in this article to prepare everything and and set up a Step Function which will be called from a dedicated “Proxy” Lambda Function.

Additionally install the aws-sdk module which we will need for actually invoking our Step Function

npm install --save aws-sdk

Create Lambda Function

Now we are good to go, so lets create a new project using the Serverless Framework and define our Step Machine

Prepare Environment

The Serverless Framework allows to define access rights inside the serverless.yml. We need to grant the permission for starting Step Functions as followed

provider:
name: aws
runtime: nodejs6.10
region: us-east-1
iamRoleStatements:
- Effect: Allow
Action:
- states:StartExecution
Resource: "*"

Reference to the Step Function

Now the interesting part. We are going to define an output resource named StateMachine and assign a reference to our Step Function. Later we set this resource as a value for an environment variable of the “Proxy” Lambda.

resources:
Outputs:
StateMachine:
Description: The ARN of the provisioning state machine
Value:
Ref: Hellostepfunc1

NOTE: Even though the name of the Step Function begins with a lower letter we have to reference it here using a capital letter, don’t ask me why.

Define “Proxy” Lambda

Let’s finally define our “Proxy” Lambda, which invokes the Step Function

var aws = require('aws-sdk')
module.exports.proxy = (event, context, callback) => {
var params = {
stateMachineArn: process.env.statemachine_arn,
input: JSON.stringify({})
}
var stepfunctions = new aws.StepFunctions()
stepfunctions.startExecution(params, function (err, data) {
if (err) {
console.log('err while executing step function')
} else {
console.log('started execution of step function')
}
})
}

Note that we have to set the ARN of the Step Function in order to invoke it. In the last step we introduced a resource which holds this ARN. In the next step we will see how to actually use it.

Define handler

The last step is to connect our functions to the respective Lambda Function handlers in the serverless.yml. Note that this time we also specify a environment variable. Here we use the resource we created to assigns the value of the resource to the environment variable called statemachine_arn. With this technique you can reference Step Functions. Quite easy, right?

functions:
...
proxy:
handler: handler.proxy
environment:
statemachine_arn: ${self:resources.Outputs.StateMachine.Value}

Deploy Functions

At this point we could deploy our Lambda and Step Functions

serverless deploy -v

You should see verbose output and If everything went fine you can see your Functions in the respective AWS console view. Just be sure to select the right region.

Note: Referencing a Step Function this way seems not to work when using the serverless-offline plugin, at least for me it didn’t.

Invoke Lambda Function

Now you can invoke the Lambda and you should see an output which says that the Step Function execution started

serverless invoke -f proxy -l

Well that’s it, have fun playing around with AWS Lambda and Step Functions. I would love to hear any feedback.

Cheers

Noah

Links

--

--

Noah Ispas

Creator of code, articles, and ceramics. Cloud-native advocate. Tech enthusiast focused on developer productivity. CNCF & Kubernetes community member.