AWSのStepFunctions入門ガイド:サーバーレスワークフローをオーケストレーションする方法のヒーロー画像

AWSのStepFunctions入門ガイド:サーバーレスワークフローをオーケストレーションする方法


AWSのStepFunctions入門ガイド

AWS StepFunctionsはAWSのサーバーレスワークフローサービスで、複数のAWSサービスを簡単に連携させ、ビジネスアプリケーションを構築するためのビジュアルワークフローを提供します。このガイドでは、StepFunctionsの基本概念から実際の利用方法、そして運用のベストプラクティスまでを解説します。

StepFunctionsとは何か

AWS StepFunctionsは、分散アプリケーションのコンポーネントをビジュアルワークフローを使用してオーケストレーションするAWSのサーバーレスオーケストレーションサービスです。「ステートマシン」という概念を使用してアプリケーションのワークフローを構築します。

StepFunctionsの主な特徴は以下の通りです:

  • ビジュアルワークフロー: 直感的なグラフィカルコンソールでワークフローを設計・ビジュアル化
  • サーバーレス: インフラの管理なしで実行できる完全マネージドサービス
  • 耐障害性: 自動的にエラー処理と再試行を管理
  • 組み込み状態: 条件分岐、並列処理、待機など、複雑なワークフローを表現するための豊富な状態タイプ
  • サービス統合: 200以上のAWSサービスとの直接統合
  • ワークフロータイプ: スタンダードワークフロー(長時間実行可能)とエクスプレスワークフロー(短時間・高ボリューム処理用)
  • モニタリング: 実行中のワークフローをリアルタイムで追跡

StepFunctionsのユースケース

StepFunctionsは様々なシナリオで活用できます:

  1. データ処理パイプライン: ETLジョブの調整、大規模データ処理
  2. マイクロサービスオーケストレーション: 複数のマイクロサービスやAPI間の連携
  3. 長時間実行バッチプロセス: 複数のステップを持つバッチジョブの管理
  4. CI/CDパイプライン: ビルド、テスト、デプロイプロセスの自動化
  5. 注文処理ワークフロー: 注文の受付から配送までの複数ステップを調整
  6. 機械学習ワークフロー: データ前処理、モデルトレーニング、推論の自動化

StepFunctionsの基本概念

ステートマシン

StepFunctionsの中心となる概念は「ステートマシン」です。ステートマシンはJSON形式の「Amazon States Language」で定義され、各種状態(State)の集合とその遷移ルールから構成されます。

状態(State)タイプ

StepFunctionsには以下のような状態タイプがあります:

  • Task: Lambda関数やAWSサービスを呼び出す
  • Choice: 条件に基づいて分岐する
  • Parallel: 複数の実行ブランチを並行して処理する
  • Map: データセットの各項目に対して繰り返し処理を行う
  • Wait: 指定した時間だけ待機する
  • Succeed/Fail: 実行を成功/失敗として終了する
  • Pass: 入力をそのまま出力に渡す(データ変換も可能)

実行(Execution)

ステートマシンは「実行」という単位で動作します。各実行は一意のIDを持ち、入力データを受け取り、状態間を遷移しながら最終的に出力データを生成します。

主要なサービス統合

StepFunctionsは200以上のAWSサービスと統合されています。特に頻繁に使用される統合には以下のようなものがあります:

1. AWS Lambda

サーバーレス関数を実行してデータ処理やビジネスロジックを実装します。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:ProcessData",
    "Payload.$": "$"
  },
  "Next": "NextState"
}

2. Amazon SQS / SNS

メッセージングおよび通知サービスと連携します。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::sqs:sendMessage",
  "Parameters": {
    "QueueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
    "MessageBody.$": "$"
  },
  "Next": "NextState"
}

3. AWS Batch

大規模なバッチコンピューティングジョブを実行します。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::batch:submitJob.sync",
  "Parameters": {
    "JobName": "StepFunctionsBatchJob",
    "JobDefinition": "arn:aws:batch:us-east-1:123456789012:job-definition/BatchJobDef:1",
    "JobQueue": "arn:aws:batch:us-east-1:123456789012:job-queue/BatchJobQueue"
  },
  "Next": "NextState"
}

4. Amazon DynamoDB

NoSQLデータベースとの読み書き操作を行います。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::dynamodb:putItem",
  "Parameters": {
    "TableName": "MyTable",
    "Item": {
      "id": {"S.$": "$.id"},
      "data": {"S.$": "$.payload"}
    }
  },
  "Next": "NextState"
}

5. AWS Glue

ETLジョブを開始および管理します。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::glue:startJobRun.sync",
  "Parameters": {
    "JobName": "my-glue-job"
  },
  "Next": "NextState"
}

6. Amazon ECS / Fargate

コンテナベースのタスクを実行します。

{
  "Type": "Task",
  "Resource": "arn:aws:states:::ecs:runTask.sync",
  "Parameters": {
    "Cluster": "default",
    "TaskDefinition": "arn:aws:ecs:us-east-1:123456789012:task-definition/MyTaskDef:1",
    "LaunchType": "FARGATE",
    "NetworkConfiguration": {
      "AwsvpcConfiguration": {
        "Subnets": ["subnet-12345678"],
        "SecurityGroups": ["sg-12345678"],
        "AssignPublicIp": "ENABLED"
      }
    }
  },
  "Next": "NextState"
}

スタンダードワークフローとエクスプレスワークフロー

StepFunctionsには2種類のワークフロータイプがあります:

スタンダードワークフロー

  • 最大1年間の実行期間
  • 完全に監査可能な実行履歴
  • 厳密に一度だけ実行するタスク処理
  • 料金: 状態遷移数に基づく
  • ユースケース: 長時間実行するワークフロー、人間の承認を含むプロセス

エクスプレスワークフロー

  • 最大5分間の実行期間
  • Amazon CloudWatch Logsへの実行履歴
  • 少なくとも1回の実行保証(重複実行の可能性あり)
  • 料金: 実行回数と実行時間に基づく
  • ユースケース: 高ボリュームのイベント処理、IoTデータ取り込み、ストリーミングデータ処理

StepFunctionsのベストプラクティス

エラー処理の実装

堅牢なワークフローを構築するには適切なエラー処理が不可欠です:

{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:ProcessData"
  },
  "Retry": [
    {
      "ErrorEquals": ["States.TaskFailed", "States.Timeout"],
      "IntervalSeconds": 3,
      "MaxAttempts": 2,
      "BackoffRate": 1.5
    }
  ],
  "Catch": [
    {
      "ErrorEquals": ["States.ALL"],
      "Next": "ErrorHandlingState"
    }
  ],
  "Next": "NextState"
}

入出力処理の最適化

InputPathやOutputPathを使って、データの流れを制御します:

{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {
    "FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:ProcessData",
    "Payload.$": "$.data"
  },
  "InputPath": "$.records",
  "OutputPath": "$.Payload",
  "ResultPath": "$.processedData",
  "Next": "NextState"
}

サービス統合パターンの選択

統合方法には3つのパターンがあります:

  1. Request Response: サービスを呼び出し、即座に次の状態に進む
  2. Run a Job (.sync): ジョブが完了するまで待機する
  3. Wait for Callback (.waitForTaskToken): 外部プロセスからのコールバックを待つ
{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
  "Parameters": {
    "FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:WaitForHumanApproval",
    "Payload": {
      "token.$": "$$.Task.Token",
      "input.$": "$"
    }
  },
  "Next": "NextState"
}

実践的な応用例:注文処理ワークフロー

実際のユースケースとして、ECサイトの注文処理ワークフローを考えてみましょう。

{
  "Comment": "ECサイト注文処理ワークフロー",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ValidateOrder",
      "Next": "CheckInventory"
    },
    "CheckInventory": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:CheckInventory",
      "Next": "InventoryChoice"
    },
    "InventoryChoice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.inventoryAvailable",
          "BooleanEquals": true,
          "Next": "ProcessPayment"
        }
      ],
      "Default": "NotifyOutOfStock"
    },
    "NotifyOutOfStock": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "arn:aws:sns:us-east-1:123456789012:OutOfStockTopic",
        "Message.$": "$"
      },
      "End": true
    },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ProcessPayment",
      "Next": "PaymentChoice"
    },
    "PaymentChoice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.paymentSuccessful",
          "BooleanEquals": true,
          "Next": "ParallelProcessing"
        }
      ],
      "Default": "NotifyPaymentFailure"
    },
    "NotifyPaymentFailure": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "arn:aws:sns:us-east-1:123456789012:PaymentFailureTopic",
        "Message.$": "$"
      },
      "End": true
    },
    "ParallelProcessing": {
      "Type": "Parallel",
      "Branches": [
        {
          "StartAt": "UpdateDatabase",
          "States": {
            "UpdateDatabase": {
              "Type": "Task",
              "Resource": "arn:aws:lambda:us-east-1:123456789012:function:UpdateOrderDB",
              "End": true
            }
          }
        },
        {
          "StartAt": "SendConfirmation",
          "States": {
            "SendConfirmation": {
              "Type": "Task",
              "Resource": "arn:aws:states:::ses:sendEmail",
              "Parameters": {
                "Destination": {
                  "ToAddresses.$": "$.customerEmail"
                },
                "Message": {
                  "Body": {
                    "Text": {
                      "Data.$": "$.orderConfirmation"
                    }
                  },
                  "Subject": {
                    "Data": "注文確認"
                  }
                },
                "Source": "orders@example.com"
              },
              "End": true
            }
          }
        }
      ],
      "Next": "PrepareShipment"
    },
    "PrepareShipment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:PrepareShipment",
      "End": true
    }
  }
}

このワークフローは以下のステップを実行します:

  1. 注文の検証
  2. 在庫の確認
  3. 支払い処理
  4. 並列処理(データベース更新とメール送信)
  5. 出荷準備

まとめ

AWS StepFunctionsは、複雑なワークフローをビジュアル化し、耐障害性のあるアプリケーションを構築するための強力なツールです。Lambda関数やその他のAWSサービスと組み合わせることで、スケーラブルでメンテナンスが容易なアーキテクチャを実現できます。

サーバーレスアプリケーションの開発において、StepFunctionsはビジネスロジックを明確に表現し、各コンポーネントの責任を分離するのに役立ちます。これにより、開発チームは個々のタスクに集中でき、アプリケーション全体の信頼性と保守性が向上します。

AWS StepFunctionsを活用して、複雑なビジネスプロセスを効率的にオーケストレーションしましょう。