Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China.
Creating a Lambda State Machine for Step Functions
Using the Amazon CDK
This tutorial shows you how to create an Amazon Step Functions state machine containing an Amazon Lambda
function using the Amazon Cloud Development Kit (Amazon CDK). The Amazon CDK is an Infrastructure as Code (IAC) framework that
lets you define Amazon infrastructure using a full-fledged programming language. You can
write an app in one of the CDK's supported languages containing one or more stacks.
Then, you can synthesize it to an Amazon CloudFormation template and deploy it to your Amazon account. We'll
use this method to define an Amazon Step Functions state machine containing an Amazon Lambda function, then
use the Amazon Web Services Management Console to initiate execution of the state machine.
Before you begin this tutorial, you must set up your Amazon CDK development environment as
described in Getting
Started With the Amazon CDK - Prerequisites Then, install the Amazon CDK with the
following command at the Amazon CLI:
npm install -g aws-cdk
This tutorial produces the same result as Creating a Lambda state machine
for Step Functions using
Amazon CloudFormation. However, in this tutorial, the
Amazon CDK doesn't require you to create any IAM roles; the Amazon CDK does it for you. The Amazon CDK
version also includes a Succeed step to illustrate how to add additional steps to your state
machine.
To deploy a sample serverless application that starts a Step Functions workflow using Amazon CDK with TypeScript to your Amazon Web Services account, see Module 10 - Deploy with Amazon CDK of The Amazon Step Functions Workshop.
Step 1: Set Up Your Amazon CDK
Project
First, create a directory for your new Amazon CDK app and initialize the project.
Be sure to name the directory step
. The Amazon CDK application
template uses the name of the directory to generate names for source files and
classes. If you use a different name, your app will not match this tutorial.
- TypeScript
-
mkdir step
cd step
cdk init --language typescript
- JavaScript
-
mkdir step
cd step
cdk init --language javascript
- Python
-
mkdir step
cd step
cdk init --language python
After the project has been initialized, activate the project's virtual
environment and install the Amazon CDK's baseline dependencies.
source .venv/bin/activate
python -m pip install -r requirements.txt
- Java
-
mkdir step
cd step
cdk init --language java
- C#
-
mkdir step
cd step
cdk init --language csharp
Next, install the construct library modules for Amazon Lambda and Amazon Step Functions.
- TypeScript
-
npm install @aws-cdk/aws-lambda @aws-cdk/aws-stepfunctions @aws-cdk/aws-stepfunctions-tasks
- JavaScript
-
npm install @aws-cdk/aws-lambda @aws-cdk/aws-stepfunctions @aws-cdk/aws-stepfunctions-tasks
- Python
-
python -m pip install aws-cdk.aws-lambda aws-cdk.aws-stepfunctions
python -m pip install aws-cdk.aws-stepfunctions-tasks
- Java
-
To build your app, run mvn compile
or use your Java IDE's Build command.
- C#
-
dotnet add src\Step package Amazon.CDK.AWS.Lambda
dotnet add src\Step package Amazon.CDK.AWS.Stepfunctions
dotnet add src\Step package Amazon.CDK.AWS.Stepfunctions.Tasks
You may also install the indicated packages using the Visual Studio NuGet
GUI, available via Tools > NuGet Package
Manager > Manage NuGet Packages for
Solution.
Once you've installed these modules, you can use them in your Amazon CDK app by importing
the following
packages:
- TypeScript
-
@aws-cdk/aws-lambda
@aws-cdk/aws-stepfunctions
@aws-cdk/aws-stepfunctions-tasks
- JavaScript
-
@aws-cdk/aws-lambda
@aws-cdk/aws-stepfunctions
@aws-cdk/aws-stepfunctions-tasks
- Python
-
aws_cdk.aws_lambda
aws_cdk.aws_stepfunctions
aws_cdk.aws_stepfunctions_tasks
- Java
-
software.amazon.awscdk.services.lambda
software.amazon.awscdk.services.stepfunctions
software.amazon.awscdk.services.stepfunctions.tasks
- C#
-
Amazon.CDK.AWS.Lambda
Amazon.CDK.AWS.StepFunctions
Amazon.CDK.AWS.StepFunctions.Tasks
Step 2: Use the Amazon CDK to Create a
Lambda State Machine
First, we'll present the individual pieces of code that define the Lambda function and
the Step Functions state machine. Then, we'll explain how to put them together in your Amazon CDK app.
Finally, you'll see how to synthesize and deploy these resources.
To create a Lambda
function
The following Amazon CDK code defines the Lambda function, providing its source code
inline.
- TypeScript
-
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
code: lambda.Code.fromInline(`
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
`),
runtime: lambda.Runtime.NODEJS_12_X,
handler: "index.handler",
timeout: cdk.Duration.seconds(25)
});
- JavaScript
-
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
code: lambda.Code.fromInline(`
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
`),
runtime: lambda.Runtime.NODEJS_12_X,
handler: "index.handler",
timeout: cdk.Duration.seconds(25)
});
- Python
-
hello_function = lambda_.Function(self, "MyLambdaFunction",
code=lambda_.Code.from_inline("""
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
}"""),
runtime=lambda_.Runtime.NODEJS_12_X,
handler="index.handler",
timeout=cdk.Duration.seconds(25))
- Java
-
Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
.code(Code.fromInline(
"exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );}"))
.runtime(Runtime.NODEJS_12_X)
.handler("index.handler")
.timeout(Duration.seconds(25))
.build();
- C#
-
var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
{
Code = Code.FromInline(@"`
exports.handler = (event, context, callback) => {
callback(null, 'Hello World!');
}"),
Runtime = Runtime.NODEJS_12_X,
Handler = "index.handler",
Timeout = Duration.Seconds(25)
});
You can see in this short example code:
-
The function's logical name, MyLambdaFunction
.
-
The source code for the function, embedded as a string in the source code
of the Amazon CDK app.
-
Other function attributes, such as the runtime to be used (Node 12.x), the
function's entry point, and a timeout.
To create a Lambda state
machine
Our state machine has two states: our Lambda function task, and a success state.
The function requires that we create a Step Functions Task that invokes our function. This
task state is used as the first step in our state machine The success state is added
to the state machine using that task's next()
method. The following
code both invokes the function MyLambdaTask
, then uses the
next()
method to set a success state of
GreetedWorld
- TypeScript
-
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
lambdaFunction: helloFunction
}).next(new sfn.Succeed(this, "GreetedWorld"))
});
- JavaScript
-
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
lambdaFunction: helloFunction
}).next(new sfn.Succeed(this, "GreetedWorld"))
});
- Python
-
state_machine = sfn.StateMachine(self, "MyStateMachine",
definition=tasks.LambdaInvoke(self, "MyLambdaTask",
lambda_function=hello_function).next(
sfn.Succeed(self, "GreetedWorld")))
- Java
-
StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
.definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
.lambdaFunction(helloFunction)
.build()
.next(new Succeed(this, "GreetedWorld")))
.build();
- C#
-
var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps {
Definition = new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
{
LambdaFunction = helloFunction
}).next(new Succeed(this, "GreetedWorld"))
});
To build and deploy the Amazon CDK
app
In your newly created Amazon CDK project, edit the file that contains the stack's
definition to look like the following example code. You'll recognize the definitions
of the Lambda function and the Step Functions state machine from previous sections.
- TypeScript
-
Update lib/step-stack.ts
with the following
code:
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as sfn from '@aws-cdk/aws-stepfunctions';
import * as tasks from '@aws-cdk/aws-stepfunctions-tasks';
export class StepStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
code: lambda.Code.fromInline(`
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
`),
runtime: lambda.Runtime.NODEJS_12_X,
handler: "index.handler",
timeout: cdk.Duration.seconds(3)
});
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
lambdaFunction: helloFunction
}).next(new sfn.Succeed(this, "GreetedWorld"))
});
}
}
- JavaScript
-
Update lib/step-stack.js
with the following
code.
const cdk = require('@aws-cdk/core');
const lambda = require('@aws-cdk/aws-lambda');
const sfn = require('@aws-cdk/aws-stepfunctions');
const tasks = require('@aws-cdk/aws-stepfunctions-tasks');
class StepStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
code: lambda.Code.fromInline(`
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
`),
runtime: lambda.Runtime.NODEJS_12_X,
handler: "index.handler",
timeout: cdk.Duration.seconds(25)
});
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
lambdaFunction: helloFunction
}).next(new sfn.Succeed(this, "GreetedWorld"))
});
}
}
module.exports = { StepStack }
- Python
-
Update step/step_stack.py
with the following
code.
from aws_cdk import core as cdk
from aws_cdk import aws_lambda as lambda_
from aws_cdk import aws_cdk.aws_stepfunctions as sfn
from aws_cdk import aws_stepfunctions_tasks as tasks
class StepStack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
hello_function = lambda_.Function(self, "MyLambdaFunction",
code=lambda_.Code.from_inline("""
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
}"""),
runtime=lambda_.Runtime.NODEJS_12_X,
handler="index.handler",
timeout=cdk.Duration.seconds(25))
state_machine = sfn.StateMachine(self, "MyStateMachine",
definition=tasks.LambdaInvoke(self, "MyLambdaTask",
lambda_function=hello_function).next(
sfn.Succeed(self, "GreetedWorld")))
- Java
-
Update src/main/java/com.myorg/StepStack.java
with the following code.
package com.myorg;
import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.core.Duration;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.stepfunctions.StateMachine;
import software.amazon.awscdk.services.stepfunctions.Succeed;
import software.amazon.awscdk.services.stepfunctions.tasks.LambdaInvoke;
public class StepStack extends Stack {
public StepStack(final Construct scope, final String id) {
this(scope, id, null);
}
public StepStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
.code(Code.fromInline(
"exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );"))
.runtime(Runtime.NODEJS_12_X)
.handler("index.handler")
.timeout(Duration.seconds(25))
.build();
StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
.definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
.lambdaFunction(helloFunction)
.build()
.next(new Succeed(this, "GreetedWorld")))
.build();
}
}
- C#
-
Update scr/Step/StepStack.cs
with the following
code.
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.StepFunctions;
using Amazon.CDK.AWS.StepFunctions.Tasks;
namespace Step
{
public class StepStack : Stack
{
internal StepStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
{
Code = Code.FromInline(@"`
exports.handler = (event, context, callback) => {
callback(null, 'Hello World!');
}"),
Runtime = Runtime.NODEJS_12_X,
Handler = "index.handler",
Timeout = Duration.Seconds(25)
});
var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps {
Definition = new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
{
LambdaFunction = helloFunction
}).Next(new Succeed(this, "GreetedWorld"))
});
}
}
}
Save the source file.Then, run the cdk synth
command in the app's
main directory. The Amazon CDK runs the app and synthesizes an Amazon CloudFormation template from it.
The Amazon CDK then displays the template.
To actually deploy the Lambda function and the Step Functions state machine to your Amazon
account, issue cdk deploy
. You'll be asked to approve the IAM
policies the Amazon CDK has generated.
Step 3: Start a State Machine
Execution
After you create your Lambda state machine, you can start an execution.
To start the state machine
execution
-
Open the Step Functions
console and choose the name of the state machine that you
created using the Amazon CDK.
-
On the
MyStateMachine-ABCDEFGHIJ1K
page, choose New execution.
The New execution page is displayed.
(Optional) To identify your execution, you can specify a name for
it in the Name box. By default, Step Functions generates a
unique execution name automatically.
Step Functions allows you to create state machine, execution, and
activity names that contain non-ASCII characters. These
non-ASCII names don't work with Amazon CloudWatch. To ensure that you
can track CloudWatch metrics, choose a name that uses only ASCII characters.
-
Choose Start Execution.
A new execution of your state machine starts, and a new page showing your
running execution is displayed.
-
(Optional) In the Execution Details, review the
Execution Status and the
Started and Closed
timestamps.
-
To view the results of your execution, choose
Output.
Step 4: Clean Up
After you've tested your state machine, we recommend that you remove both your state
machine and the related Lambda function to free up resources in your Amazon Web Services account. Run
the cdk destroy
command in your app's main directory to remove your state
machine.
Next steps
To learn more about developing Amazon infrastructure using the Amazon CDK, see the Amazon CDK Developer Guide.
For information about writing Amazon CDK apps in your language of choice, see:
- TypeScript
-
Working with the
Amazon CDK in TypeScript
- JavaScript
-
Working with the
Amazon CDK in JavaScript
- Python
-
Working with the Amazon CDK
in Python
- Java
-
Working with the Amazon CDK in Java
- C#
-
Working with the Amazon CDK
in C#
For more information on the Amazon Construct Library modules used in this tutorial, see
the Amazon CDK API Reference overviews below.