In this tutorial, you will create a AWS Lambda function using AWS CloudFormation. You'll use
the AWS CloudFormation console and a YAML template to create a stack (IAM
roles, the Lambda function, and the state machine). Then, you'll use the Step Functions console to
start the state machine execution.
For more information, see Working with
CloudFormation Templates and the AWS::StepFunctions::StateMachine
resource in the
AWS CloudFormation User Guide.
Step 1: Set up your AWS CloudFormation template
Before you use the example
templates, you should understand how to declare the different parts of an AWS CloudFormation
template.
To create an IAM
role for Lambda
Define the trust policy associated with the IAM role for the Lambda function. The
following examples define a trust policy using either YAML or JSON.
- YAML
-
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
- JSON
-
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
To create a Lambda
function
Define the following properties for a Lambda function that will print the message
Hello World
.
Ensure that your Lambda function is under the same AWS account and AWS Region as your state machine.
- YAML
-
MyLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role: !GetAtt [ LambdaExecutionRole, Arn ]
Code:
ZipFile: |
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
Runtime: "nodejs12.x"
Timeout: "25"
- JSON
-
"MyLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
},
"Code": {
"ZipFile": "exports.handler = (event, context, callback) => {\n callback(null, \"Hello World!\");\n};\n"
},
"Runtime": "nodejs12.x",
"Timeout": "25"
}
},
To create an IAM role for the
state machine execution
Define the trust policy associated with the IAM role for the state machine
execution.
- YAML
-
StatesExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- !Sub states.${AWS::Region}.amazonaws.com
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: StatesExecutionPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "lambda:InvokeFunction"
Resource: "*"
- JSON
-
"StatesExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::Sub": "states.${AWS::Region}.amazonaws.com"
}
]
},
"Action": "sts:AssumeRole"
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "StatesExecutionPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*"
}
]
}
}
]
}
},
To create a Lambda state machine
Define the Lambda state machine.
- YAML
-
MyStateMachine:
Type: "AWS::StepFunctions::StateMachine"
Properties:
DefinitionString:
!Sub
- |-
{
"Comment": "A Hello World example using an AWS Lambda function",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "${lambdaArn}",
"End": true
}
}
}
- {lambdaArn: !GetAtt [ MyLambdaFunction, Arn ]}
RoleArn: !GetAtt [ StatesExecutionRole, Arn ]
- JSON
-
"MyStateMachine": {
"Type": "AWS::StepFunctions::StateMachine",
"Properties": {
"DefinitionString": {
"Fn::Sub": [
"{\n \"Comment\": \"A Hello World example using an AWS Lambda function\",\n \"StartAt\": \"HelloWorld\",\n \"States\": {\n \"HelloWorld\": {\n \"Type\": \"Task\",\n \"Resource\": \"${lambdaArn}\",\n \"End\": true\n }\n }\n}",
{
"lambdaArn": {
"Fn::GetAtt": [
"MyLambdaFunction",
"Arn"
]
}
}
]
},
"RoleArn": {
"Fn::GetAtt": [
"StatesExecutionRole",
"Arn"
]
}
}
}
Step 2: Use the AWS CloudFormation template to create a
Lambda State Machine
Once you understand the components of the AWS CloudFormation template, you can put them together
and use the template to create an AWS CloudFormation stack.
To create the Lambda state
machine
-
Copy the following example data to a file named MyStateMachine.yaml
for the YAML example, or MyStateMachine.json
for JSON.
- YAML
-
AWSTemplateFormatVersion: "2010-09-09"
Description: "An example template with an IAM role for a Lambda state machine."
Resources:
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
MyLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role: !GetAtt [ LambdaExecutionRole, Arn ]
Code:
ZipFile: |
exports.handler = (event, context, callback) => {
callback(null, "Hello World!");
};
Runtime: "nodejs12.x"
Timeout: "25"
StatesExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- !Sub states.${AWS::Region}.amazonaws.com
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: StatesExecutionPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "lambda:InvokeFunction"
Resource: "*"
MyStateMachine:
Type: "AWS::StepFunctions::StateMachine"
Properties:
DefinitionString:
!Sub
- |-
{
"Comment": "A Hello World example using an AWS Lambda function",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "${lambdaArn}",
"End": true
}
}
}
- {lambdaArn: !GetAtt [ MyLambdaFunction, Arn ]}
RoleArn: !GetAtt [ StatesExecutionRole, Arn ]
- JSON
-
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "An example template with an IAM role for a Lambda state machine.",
"Resources": {
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
},
"MyLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
},
"Code": {
"ZipFile": "exports.handler = (event, context, callback) => {\n callback(null, \"Hello World!\");\n};\n"
},
"Runtime": "nodejs12.x",
"Timeout": "25"
}
},
"StatesExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
{
"Fn::Sub": "states.${AWS::Region}.amazonaws.com"
}
]
},
"Action": "sts:AssumeRole"
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "StatesExecutionPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*"
}
]
}
}
]
}
},
"MyStateMachine": {
"Type": "AWS::StepFunctions::StateMachine",
"Properties": {
"DefinitionString": {
"Fn::Sub": [
"{\n \"Comment\": \"A Hello World example using an AWS Lambda function\",\n \"StartAt\": \"HelloWorld\",\n \"States\": {\n \"HelloWorld\": {\n \"Type\": \"Task\",\n \"Resource\": \"${lambdaArn}\",\n \"End\": true\n }\n }\n}",
{
"lambdaArn": {
"Fn::GetAtt": [
"MyLambdaFunction",
"Arn"
]
}
}
]
},
"RoleArn": {
"Fn::GetAtt": [
"StatesExecutionRole",
"Arn"
]
}
}
}
}
}
-
Open the AWS CloudFormation
console and choose Create Stack.
-
On the Select Template page, choose Upload a
template to Amazon S3. Choose your MyStateMachine
file, and
then choose Next.
-
On the Specify Details page, for Stack
name, enter MyStateMachine
, and then choose
Next.
-
On the Options page, choose Next.
-
On the Review page, choose I acknowledge that AWS CloudFormation
might create IAM resources. and then choose
Create.
AWS CloudFormation begins to create the MyStateMachine
stack and displays the
CREATE_IN_PROGRESS status. When the process is complete, AWS CloudFormation
displays the CREATE_COMPLETE status.
-
(Optional) To display the resources in your stack, select the stack and choose the
Resources tab.
Step 3: Start a State Machine
execution
After you create your Lambda state machine, you can start its execution.
To start the state machine
execution
-
Open the Step Functions console and
choose the name of the state machine that you created using AWS CloudFormation.
-
On the MyStateMachine-ABCDEFGHIJ1K
page, choose New execution.
The New execution page is displayed.
(Optional) Enter a custom execution name to override the generated default.
Non-ASCII names and logging
Step Functions accepts names for state machines, executions, activities, and labels that contain non-ASCII characters. Because such characters will not work with Amazon CloudWatch, we recommend using only ASCII characters so you can track metrics in CloudWatch.
-
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.