はじめに

こんにちは、アジャイル事業部のヤマダ(北野)です。

この記事は「Building Production-Grade Workflow Patterns with AWS Step Functions (API313)」のセッションレポートです。

AWSのPrincipal Developer AdvocateであるEric Johnson氏が、Step Functionsを使った本番運用レベルのワークフローパターンについて解説されました。

概要

Take your AWS Step Functions expertise to the next level with advanced architectural patterns and best practices. Join this session to dive deep into when and how to effectively use Map states, Parallel states, and nested workflows in production environments. Learn how to leverage features such as JSONata support, variables, and private API endpoint connections to build secure, high-performance workflows while optimizing costs. Through real-world production scenarios, discover proven patterns for building resilient serverless applications that scale.

このセッションは、Step Functionsの専門知識を深めたい方向けです。本番環境で必須となるMap、Parallel、ネストされたワークフローといった高度なアーキテクチャパターンに焦点を当てます。JSONata、変数、プライベートAPI接続などの機能を活用し、コストを最適化しつつ、セキュアで高性能なワークフローを構築する具体的な手法を紹介します。実世界での事例に基づき、高い拡張性と耐障害性を備えたサーバーレスアプリケーションを実現する、実証済みのベストプラクティスを学べます。

Tonyのピザビジネスが抱えていた課題

Tony のピザビジネスの紹介
オーケストレーションの問題を強調する引用

Eric氏は年間430万件の注文を処理するまでに成長したTonyのビジネスを例に、最初のアーキテクチャが抱えていた問題を指摘しました。それはLambda関数が別のLambda関数を呼び出す、いわゆる「スパゲッティアーキテクチャ」です。

「これはLambdaの問題ではなく、オーケストレーション(処理の全体管理)の問題です」と強調されていました。単一機能には優れたLambdaも、その連携が複雑になると管理が困難になります。

この「スパゲッティアーキテクチャ」は、成長初期のシステムで非常によく見られるパターンだと思います。特に1人での開発で取り急ぎを連発してスピードを重視してしまうとなりがちな印象です。

Step Functionsの5つの主要な強み

Step Functions の 5 つのスーパーパワー

Eric氏は、Step Functionsを活用すべき理由として「5つのスーパーパワー」を挙げました。

1. ビジュアルデザインとIaC連携

ドラッグ&ドロップのビジュアルデザイン機能

ドラッグ&ドロップのビジュアルエディタに加え、IDE内でASL(Amazon States Language)ファイルから直接ビジュアル化できるツール連携が強調されました。

2. 直接サービス統合

Lambda の適切な使い方に関する引用

Lambdaを介さず、DynamoDBやS3などのAWSサービスを直接呼び出せます。この際、「Lambda は輸送ではなく、変換に使う」という原則が重要とされました。

これは私が一番好きなスーパーパワーです。ラーメンタイマーの際にも最も意識した部分ですね。

3. 組み込みエラーハンドリング

組み込みエラーハンドリング機能

Catchブロックによる簡潔なエラー処理や、Dead Letter Queue(DLQ)の設定が容易です。これにより、煩雑なリトライロジックを自前で書く必要がなくなります。

4. データ変換

JSONataを用いて、ステップの開始時や終了時にデータの整形・変換を効率的に行えます。「Passステートを99%削減できる」という指摘は、初学者にとって重要な最適化のヒントです。

私もJSONataに無限の可能性は感じるものの、けっこう初見だとハードルを感じる気もします。

5. 高度なワークフロー

分散マップによる大規模並列処理

条件分岐、並列処理に加え、特に分散マップ(Distributed Map)による大規模並列処理が紹介されました。NFLが画像処理時間を4〜6週間から32秒に短縮し、約$50,000を削減した事例は圧巻でした。

Step Functionsの料金体系を理解する

Express と Standard の料金体系比較

コスト最適化のために料金体系を理解することの重要性を強調されていました。

Express Step Functions

  • リクエストベース: $1 / 100万リクエスト
  • 実行時間ベース: 1ペニーで約600GB のコンピュート
  • 大量処理、短時間実行、コスト重視の場合に適している

Standard Step Functions

  • ステート遷移ベース: $0.025 / 1,000ステート遷移
  • 開始と終了もステート遷移としてカウントされる
  • 長時間実行、複雑なロジック、監査要件がある場合に適している

コスト最適化の核心: ポーリングの排除

最初のワークフローは、主にStandard Step Functionsと複数のLambda関数に依存し、月額コストは$1,770でした。この高コストの最大の原因は、ポーリングによる多数のステート遷移でした。

決済や調理状況の確認において、ワークフローが「まだ終わらないか?」と定期的に確認する(ポーリング)ために、1つの注文で合計150以上のステート遷移が発生していました。

コールバックパターンへの置き換え:
「ポーリング」を、「処理完了時にStep Functionsへ通知を返す」コールバックパターンに置き換えました。これにより、ステート遷移のオーバーヘッドを大幅に削減。

結果

  • 104ステート遷移を削減。
  • 合計節約額: $1,044。新しい月額コストは$732に。

「ポーリングはうるさくて高コスト」という比喩は秀逸です。コールバックパターンは、待ち時間をステートマシンの外に出すことで、Step Functionsの課金対象となるステート遷移そのものを劇的に減らすという、コスト最適化の基本かつ最も効果的な手法だと再認識しました。

その他のコスト削減とアーキテクチャ改善

  • アクティビティパターン: VPC内のレガシーな不正検知システムを、Lambda経由ではなく Step Functionsのアクティビティパターンで連携し、さらに$587削減。新しい月額コストは$145に。
  • API Gatewayからの直接統合: 外部API呼び出しにおけるLambdaを排除し、API GatewayからStep Functionsを直接起動することで、$12削減。
  • プライベートAPI接続の最適化: HRシステムへの接続で、Amazon VPC Latticeを利用して VPC内Lambdaを削減。
  • ネストされたワークフロー(Express活用): 最適な店舗を見つける「ロケーションファインダー」ワークフローをネスト。長時間の標準ワークフローとは異なり、短時間で大量に実行されるこのサブ処理にExpress Step Functionsを適用し、$45から$17へと72%コスト削減。

本番環境の信頼性を高めるパターン

コスト削減後、システムの信頼性を高めるパターンを導入しました。

  • サーキットブレーカーパターン: 外部依存サービス(決済など)が停止している際、無駄なリクエストを送るのを防ぐために、DynamoDBを使って状態管理し、一定時間自動的に通信を遮断する仕組みを追加。
  • SAGAパターン: 分散トランザクション(決済→在庫確保→ドライバー予約)において、途中で失敗した場合に、成功した前のステップを「補償トランザクション」で自動的に取り消し(例:在庫を元に戻す、決済を返金)、データの一貫性を保つ。

この2つのパターンは、マイクロサービスや分散システムにおいて必須の設計です。特にSAGA パターンは、複雑な補償ロジックをStep Functionsのビジュアルなワークフローで表現できるため、開発者にとっての負担が大幅に軽減されるメリットは計り知れません。

最終結果とStep Functionsの役割

最終的な成果

  • 改善前コスト: $1,770 / 月
  • 改善後コスト: $212.34 / 月
  • 削減率: 88%

加えて、サーキットブレーカーやSAGAパターンといった本番レベルの信頼性向上策と、チャットボットや最適店舗検索などの先進的な新機能が実装されました。

Durable Functionsとの使い分け

Eric氏は、LambdaベースのDurable Functionsとの使い分けにも言及し、「大規模なAWSサービス間のオーケストレーションや、ビジュアルデザイン、監査要件がある場合はStep Functionsが適している」と結論づけました。

まとめ

  • オーケストレーションの問題から始める: Step Functionsは単なるコードの問題ではなく、システム全体の「状態管理」と「エラーハンドリング」の問題を解決する。
  • スマートな設計がコストを生む: ポーリングを排除し、Expressや直接統合といった適切なパターンを選ぶことがコスト最適化の鍵となる。
  • 信頼性は設計に組み込む: SAGAやサーキットブレーカーによって、手動でのリカバリを不要にし、信頼性を向上させる。

Eric氏のユーモアと実践的な解説のおかげで、Step Functionsが単なるタスク実行ツールではなく、ビジネスロジックの信頼性とコスト効率を担保する「ワークフロー・オーケストレーター」であることを深く理解できたセッションでした。