When a serverless application requires orchestration of multiple tasks—such as invoking various Lambda functions, implementing retries, or managing conditional logic—AWS Step Functions provides a robust and reliable solution.
Today, we'll integrate Step Functions into our AWS SAM project using AWS::Serverless::StateMachine.
🧱 Why Step Functions?
💡 Visual workflows
🔁 Built-in retries and error handling
🧩 Easily integrate with Lambda, DynamoDB, SQS, etc.
📉 Great observability via execution history
📦 Project Structure
Example directory layout:
.
├── template.yml
├── functions/
│ ├── taskOne.ts
│ └── taskTwo.ts
🔧 Step 1: Define Your Lambda Functions
In template.yml:
Resources:
TaskOneFunction:
Type: AWS::Serverless::Function
Properties:
Handler: functions/taskOne.handler
Runtime: nodejs22.x
TaskTwoFunction:
Type: AWS::Serverless::Function
Properties:
Handler: functions/taskTwo.handler
Runtime: nodejs22.x
Example taskOne.ts:
export const handler = async () => {
console.log("Running Task One");
return { status: "taskOne done" };
};
🔁 Step 2: Define the State Machine
In template.yml, add a new resource:
MyStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
Name: MyWorkflow
Definition:
StartAt: TaskOne
States:
TaskOne:
Type: Task
Resource: !GetAtt TaskOneFunction.Arn
Next: TaskTwo
TaskTwo:
Type: Task
Resource: !GetAtt TaskTwoFunction.Arn
End: true
Role: !GetAtt StepFunctionExecutionRole.Arn
This creates a two-step workflow: TaskOne → TaskTwo.
🔐 Step 3: Add IAM Role for Step Functions
StepFunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: states.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: StepFunctionInvokeLambda
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !GetAtt TaskOneFunction.Arn
- !GetAtt TaskTwoFunction.Arn
✅ Bonus: Add Retry Logic
TaskOne:
Type: Task
Resource: !GetAtt TaskOneFunction.Arn
Next: TaskTwo
Retry:
- ErrorEquals: ["Lambda.ServiceException", "Lambda.AWSLambdaException"]
IntervalSeconds: 2
MaxAttempts: 3
🧠 Conclusion
Using Step Functions with AWS SAM makes your serverless apps more modular, resilient, and observable.
Key benefits:
🪄 Clear separation of logic
🔁 Built-in retries and error handling
🧩 Easily scale up workflows