Step Functions

AWS のワークフローサービスで、処理の呼び出し順序 / 分岐 / 待機 / 再試行を状態遷移の定義として外に出し、その進行を AWS 側が管理する

AWSサーバーレス

Step Functions とは

AWS Step Functions は、複数の処理の呼び出し順序 / 分岐 / 待機 / 再試行を「状態と遷移」の宣言として外に出し、その進行を AWS 側が管理するワークフローサービスである。定義には ASL (Amazon States Language) を使い、各ステートが何を呼び、次にどこへ進み、失敗したら何回やり直すかまでを書き切る。

効いてくるのは図が描けることではなく、制御フローの置き場所が変わることである。関数のコードの中に再試行ループや進行状況の管理を書くと、途中で落ちたときにどこまで終わったかを自力で復元しなければならない。Step Functions は遷移ごとに実行の状態を保持するので、長い待機や人手の承認を挟んでも進行が失われない。裏返すと、状態遷移の回数が課金と所要時間の単位になるため、意味のない細分化はそのままコストと遅延に跳ね返る。

SAM での定義

状態機械そのものを 1 つのリソースとして宣言する。Task が呼び出し先を持ち、Next が遷移先、Catch が失敗時の逃げ先になる。再試行と分岐が定義側にあるため、呼ばれる関数は 1 つの仕事だけを引き受ける形に保てる。

OrderWorkflow:
  Type: AWS::Serverless::StateMachine
  Properties:
    DefinitionBody:
      StartAt: ValidateOrder
      States:
        ValidateOrder:
          Type: Task
          Resource: !GetAtt ValidateFunction.Arn
          Next: ProcessPayment
        ProcessPayment:
          Type: Task
          Resource: !GetAtt PaymentFunction.Arn
          Next: SendNotification
          Catch:
            - ErrorEquals: [PaymentFailed]
              Next: HandleFailure
        SendNotification:
          Type: Task
          Resource: !GetAtt NotifyFunction.Arn
          End: true
        HandleFailure:
          Type: Task
          Resource: !GetAtt FailureFunction.Arn
          End: true

ステートの種類

ステートは、外部を呼ぶもの (Task)、流れを変えるもの (Choice / Parallel / Map)、時間とデータを扱うもの (Wait / Pass)、終端 (Succeed / Fail) に分かれる。分岐や待機を関数の中の処理として書かず、ステートとして立てるのがこのサービスの使い方である。

ステート説明
TaskLambda や AWS サービスを呼び出す
Choice条件分岐
Parallel並列実行
Map配列の各要素を処理 (同一の実行内で回す方式と、要素群を子実行に切り出して大規模に並列化する方式がある)
Wait指定時間待機
Passデータの変換
Succeed / Fail成功 / 失敗で終了

Standard vs Express

ワークフロータイプは作成時に選ぶ。実行時間の上限だけを見て選ぶと事故になるのは、実行保証の性質そのものが違うためである。

観点StandardExpress
最大実行時間1 年5 分
課金の単位状態遷移の回数リクエスト数 + 実行時間とメモリ
実行保証Exactly-once (ASL で Retry を指定した場合を除き、タスクとステートが 2 回以上実行されない)非同期の呼び出しは At-least-once / 同期の呼び出しは At-most-once
実行履歴Step Functions が保持し、実行完了から 90 日で削除されるStep Functions は保持しない (ログ出力を有効にして初めて後から追える)
同名の実行実行中の同名の実行に対しては冪等な応答を返す冪等性は管理されず、同名でも並行して実行される
使える統合パターン完了待ち (.sync) とコールバック (.waitForTaskToken)どちらも使えない
向く処理やり直しが許されない処理 (課金 / クラスターの起動)、待機や承認を挟む長い流れ同じ入力で何度実行しても結果が変わらない処理の大量さばき

2026 年 8 月時点の米国東部 (バージニア北部) の公表価格では、Standard は状態遷移 1 回あたり $0.000025 (月 4,000 回までは無料利用枠)、Express は 100 万リクエストあたり $1.00 に $0.00001667 / GB 秒の実行時間分が加わる。見積りがずれる典型は 2 つある。やり直し 1 回も課金対象の状態遷移として数えられること、そして Map を子実行へ切り出す方式では反復 1 回ごとに状態遷移を消費すること (同一の実行内で回す方式では反復の開始で遷移が発生しない) である。遷移が多く 1 回が短い処理は Express、待機で時間を稼ぐ処理は Standard が有利になりやすい。

履歴の 90 日という保持期間は、監査や規制の都合で長すぎる場合に割り当ての申請で 30 日へ短縮できる。

Lambda を挟まない直接統合

Task の Resource に関数の ARN ではなくサービスの操作を指す ARN を書くと、Step Functions が AWS サービスを直接呼ぶ。書き方は 2 系統あり、よく使う操作をあらかじめ用意した最適化統合 (arn:aws:states:::dynamodb:putItem の形) と、SDK の API を汎用的に呼ぶ AWS SDK 統合 (arn:aws:states:::aws-sdk: で始まる形) は別物である。前者には完了待ちなどの機能が組み込まれており、後者は最適化統合が用意されていない操作を埋めるために使う。

WriteToDynamoDB:
  Type: Task
  Resource: arn:aws:states:::dynamodb:putItem
  Parameters:
    TableName: orders
    Item:
      orderId:
        S.$: $.orderId
      status:
        S: completed
  End: true

関数を経由しないので、その実行料金と初回起動の待ち時間、それに保守するコードが消える。一方で状態遷移の課金と入出力の受け渡しは残るため、費用が無くなるわけではない。値の整形が要る場合は ASL の式で足りるかを先に確かめ、条件の入り組んだ変換が必要なら関数に戻したほうが読める定義になる。

エラーハンドリング

Retry は同じステートをやり直し、Catch は別のステートへ逃がす。下の指定なら 2 秒後 / 4 秒後 / 8 秒後と間隔を倍にしながら最大 3 回やり直し、それでも失敗したら HandleFailure へ移る。States.ALL は個別に捕まえていない失敗をまとめて受ける受け皿で、これを置かないと実行そのものが失敗で終わる。やり直しの 1 回ごとに状態遷移が積まれるので、回数と間隔は費用と全体の所要時間の両方を見て決める。

ProcessPayment:
  Type: Task
  Resource: !GetAtt PaymentFunction.Arn
  Retry:
    - ErrorEquals: [ServiceException]
      IntervalSeconds: 2
      MaxAttempts: 3
      BackoffRate: 2
  Catch:
    - ErrorEquals: [States.ALL]
      Next: HandleFailure

ユースケース

処理の形は、主役に据えるステートでほぼ決まる。直列か、分岐か、要素ごとの反復か、待機かを先に見極めると定義が素直になる。

ユースケースパターン
注文処理Task → Task → Task (直列)
画像処理Map (並列処理)
承認ワークフローTask → Wait (人間の承認) → Task
ETL パイプラインParallel → Task (集約)

作る前に決めておくこと

第 1 に、ステートの間で受け渡すデータの大きさである。タスク / ステート / 実行の入出力には UTF-8 の文字列として 256 KiB という上限があり、超えれば実行が失敗する。処理対象の実体は S3 などに置き、ワークフローには置き場所を指す情報だけを流すのが基本形になる。

第 2 に、タイプは実行時間ではなく実行保証で決める。二重に走ると困る処理を非同期の Express に載せた時点で、同じ処理が 2 回実行され得る前提で冪等性を自分で作り込む義務が生じる。

第 3 に、失敗したときに何を見るかである。Express は実行履歴が Step Functions 側に残らないため、ログ出力を有効にしていなければ経過を追えない。作った後に足すのではなく、1 本目から出力先を決めておく。

共有:

この記事は役に立ちましたか?

関連用語

関連する記事