Step Functions #

In modern distributed system architecture, especially those using microservices and serverless approaches, we’re often faced with the challenge of coordinating workflows involving many independent services. For example, an e-commerce payment transaction process requires several sequential steps: validating the order, charging the credit card balance, deducting product stock from inventory, and sending a confirmation email to the buyer.

If each service triggers the next one directly using async events (the Choreography pattern), the overall workflow becomes very hard to monitor, debug, and manage when an error occurs mid-way. This is where AWS Step Functions comes in as a serverless managed orchestration solution that lets us design, run, and audit multi-step workflows as a robust, failure-tolerant State Machine.


Orchestration vs. Choreography in Microservices #

Before diving into Step Functions, it’s important to understand the difference between the two main distributed service coordination patterns:

flowchart TD
    subgraph Koreografi["Choreography Pattern"]
        direction LR
        S1["Order Service"] -->|Event| S2["Payment Service"]
        S2 -->|Event| S3["Stock Service"]
        S3 -->|Event| S4["Shipping Service"]
    end
    
    subgraph Orkestrasi["Orchestration Pattern"]
        direction TB
        Orch["AWS Step Functions<br/>(Orchestrator)"]
        Orch -->|1. Call| O1["Order Service"]
        Orch -->|2. Call| O2["Payment Service"]
        Orch -->|3. Call| O3["Stock Service"]
        Orch -->|4. Call| O4["Shipping Service"]
    end
  • Choreography: Each service works independently and reacts to events from other services. This pattern is very flexible with the lowest coupling, but the end-to-end process flow is hard to trace, and handling transaction rollback is very complex if a failure occurs at the last step.
  • Orchestration: There’s one central component (the Orchestrator) that actively manages the flow, calling services one by one, managing input/output data exchange, and controlling error handling. AWS Step Functions acts as this centralized orchestrator.

How AWS Step Functions Works #

AWS Step Functions works by defining our workflow as a State Machine. Each step in the workflow is represented as a State.

The State Machine workflow is defined declaratively using a JSON or YAML document following the Amazon States Language (ASL) rules.

flowchart TD
    Start([Start Execution]) --> Validate["Task: Validate Order<br/>(AWS Lambda)"]
    Validate --> CheckCard{"Choice: Valid?"}
    CheckCard -- "Yes" --> Charge["Task: Charge Balance<br/>(Stripe/DynamoDB)"]
    CheckCard -- "No" --> Fail1[/"Fail: Cancel (Invalid Order)"/]
    
    Charge --> CheckPayment{"Choice: Success?"}
    CheckPayment -- "Yes" --> Ship["Task: Send Confirmation Email<br/>(Amazon SES)"]
    CheckPayment -- "No" --> Refund["Task: Rollback / Refund<br/>(Saga Pattern)"]
    
    Ship --> Success([Succeed: Transaction Complete])
    Refund --> Fail2[/"Fail: Transaction Failed (Payment Rejected)"/]

Essential State Types in ASL: #

  1. Task State: Runs actual compute work. This task can trigger a Lambda function, run a Fargate container, write to DynamoDB, or make external HTTP calls.
  2. Choice State: Performs logic branching (if/else) based on input data variable values.
  3. Parallel State: Runs multiple workflow branches simultaneously (concurrently) and merges the results back after all branches complete.
  4. Map State: Iterates over an array of data, processing each array element in parallel or sequentially.
  5. Wait State: Delays the workflow for a certain duration (e.g., waiting 24 hours) or until a specific time is reached.
  6. Pass State: Runs no external compute; used only to manipulate or filter input/output data structures.
  7. Succeed / Fail State: Marks the end of workflow execution with an explicit success or failure status.

Two Workflow Types: Standard vs. Express #

AWS Step Functions provides two State Machine type options optimized for different workload characteristics:

Comparison FeatureStandard WorkflowExpress Workflow
Maximum DurationUp to 1 YearMax 5 Minutes
Execution ModelExactly-Once (guaranteed executed exactly once)At-Least-Once (possible to execute more than once)
State StorageDurable (detailed execution history stored up to 90 days)Ephemeral (execution history only sent to CloudWatch Logs)
ThroughputUp to 2,000 executions per secondUp to 100,000+ executions per second
Billing ModelPer State Transition ($0.025 per 1,000 transitions)Per execution Duration & Memory (like Lambda)
Best Use CasesLong business processes, human approvals, fund transfersIoT stream processing, high-speed REST APIs, lightweight ETL

Amazon States Language (ASL) Structure #

Here’s an example of a simple payment validation workflow written in Amazon States Language (ASL) in YAML format:

Comment: "Transaction Validation Orchestration Workflow"
StartAt: ValidateOrder
States:
  ValidateOrder:
    Type: Task
    Resource: "arn:aws:lambda:ap-southeast-1:123456789012:function:ValidateOrderFunction"
    Next: IsValid
    # ✓ Configuring automatic Retry declaratively at the platform level
    Retry:
      - ErrorEquals:
          - "States.Timeout"
          - "Lambda.ServiceException"
        IntervalSeconds: 2
        MaxAttempts: 3
        BackoffRate: 2.0
    # ✓ Redirecting the flow on permanent failure (Catch)
    Catch:
      - ErrorEquals:
          - "States.ALL"
        Next: SystemFailure

  IsValid:
    Type: Choice
    Choices:
      - Variable: "$.isValid"
        BooleanEquals: true
        Next: ProcessPayment
    Default: CancelOrder

  ProcessPayment:
    Type: Task
    Resource: "arn:aws:lambda:ap-southeast-1:123456789012:function:ProcessPaymentFunction"
    Next: TransactionComplete

  CancelOrder:
    Type: Fail
    Error: "OrderValidationError"
    Cause: "Order data is invalid after verification."

  SystemFailure:
    Type: Fail
    Error: "SystemError"
    Cause: "An internal error occurred in the execution infrastructure."

  TransactionComplete:
    Type: Succeed

Saga Transaction Pattern #

In distributed serverless transaction systems, we can’t issue instant SQL COMMIT or ROLLBACK commands across microservice databases. Instead, we must apply the Saga Pattern.

The Saga Pattern works by designing a pair of transactions: the Main Transaction and the Compensation Transaction (cancellation). If step 3 fails midway, the Step Functions orchestrator is responsible for calling the Compensation Transaction for steps 1 and 2 sequentially to restore the system data state (rollback).

With Step Functions, the Saga pattern is defined using a Catch block on each Task. If payment fails, the flow automatically jumps to the RefundPayment or CancelInventoryReservation Lambda function before stopping the workflow with a failure status.


Data Manipulation Management: Path Processing #

One of the most confusing concepts when learning Step Functions is how to filter and operate on the JSON data flowing between states. ASL provides four path filtering variables (path processing):

  1. InputPath: Filters which part of the previous state’s input JSON the current state is allowed to read.
  2. Parameters: Creates a new JSON object with values we define ourselves to send as input to the task resource (e.g., the Lambda payload).
  3. ResultPath: Determines where the current task’s output should be stored inside the main input JSON object. This is very useful if we want to insert new data without deleting old input data.
  4. OutputPath: Filters which part of the final combined result JSON is allowed to be sent to the next state.

Summary #

  • AWS Step Functions is a serverless workflow orchestrator that unifies various AWS services (Lambda, Fargate, DynamoDB) into orderly workflows.
  • Supports Standard Workflow types for long-running processes (up to 1 year) based on exactly-once, plus Express Workflows for fast (max 5 minutes), high-throughput processes.
  • Amazon States Language (ASL) is the declarative JSON/YAML-based language used to define state machines.
  • Declarative Error Handling (built-in Retry and Catch features) frees developers from writing manual retry logic inside application code.
  • The Saga Pattern can be reliably orchestrated using Step Functions to manage compensation transactions (rollback) in distributed microservice architectures.
← Previous: SNS   Next: Aurora →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact