DEV Community

Cover image for Orchestrating Workflows with AWS Step Functions and AWS SAM
Márcio Coelho
Márcio Coelho

Posted on Edited on

Orchestrating Workflows with AWS Step Functions and AWS SAM

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
Enter fullscreen mode Exit fullscreen mode

🔧 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
Enter fullscreen mode Exit fullscreen mode

Example taskOne.ts:

export const handler = async () => {
  console.log("Running Task One");
  return { status: "taskOne done" };
};
Enter fullscreen mode Exit fullscreen mode

🔁 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

✅ Bonus: Add Retry Logic

TaskOne:
  Type: Task
  Resource: !GetAtt TaskOneFunction.Arn
  Next: TaskTwo
  Retry:
    - ErrorEquals: ["Lambda.ServiceException", "Lambda.AWSLambdaException"]
      IntervalSeconds: 2
      MaxAttempts: 3

Enter fullscreen mode Exit fullscreen mode

🧠 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

Top comments (0)