AWS Step Functions をゼロからざっくり理解する

AWS Step Functions をゼロから勉強してみたので、内容をまとめました。
2020.06.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンサル部@大阪オフィスのYui(@MayForBlue)です。

以前から気になっていた AWS Step Functions をゼロから勉強してみたので、内容をまとめました。
最近アップデートも多く、アツいサービスだと思います!

AWS Step Functions とは

分散アプリケーション、マイクロサービスのコンポーネントの疎結合化を可能にするAWSのマネージドサービス。
各コンポーネントが独立するため、アプリケーションのスケール及び変更を容易にすることができます。
一つの Step Functions の定義全体をステートマシンと呼び、これらはASL(Amazon States Language)と呼ばれる独自言語を用いて記述されます。
また、ASLを用いて定義されたワークフローはマネジメントコンソール上でビジュアライズされます。

AWS Step Functions とは

ASL(Amazon States Language)

前述のとおり、Step Functions はASLと呼ばれるJSONベースの構造化言語で定義します。
以下がサンプルです。
指定するキー(フィールド)が複数あるのですが、"States"の中にタスクの識別子を指定して内容を記述していきます。

{
  "Comment": "An example of the Amazon States Language using a choice state.",
  "StartAt": "FirstState",
  "States": {
    "FirstState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FUNCTION_NAME",
      "Next": "ChoiceState"
    },
    "ChoiceState": {
      "Type" : "Choice",
      "Choices": [
        {
          "Variable": "$.foo",
          "NumericEquals": 1,
          "Next": "FirstMatchState"
        },
        {
          "Variable": "$.foo",
          "NumericEquals": 2,
          "Next": "SecondMatchState"
        }
      ],
      "Default": "DefaultState"
    },

    "FirstMatchState": {
      "Type" : "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:OnFirstMatch",
      "Next": "NextState"
    },

    "SecondMatchState": {
      "Type" : "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:OnSecondMatch",
      "Next": "NextState"
    },

    "DefaultState": {
      "Type": "Fail",
      "Error": "DefaultStateError",
      "Cause": "No Matches!"
    },

    "NextState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FUNCTION_NAME",
      "End": true
    }
  }
}

ステートマシンの内容

フィールド 内容
Comment ASLについてのコメント(概要等)
StartAt 最初に実行するState
TimeoutSeconds 処理を実行する時間
Version ASLのバージョン
States ステートマシンを構成するStateを定義する。複数のStateの指定が可能。

Stateの種類

フィールド 内容
Task ひとつの処理単位
Wait 処理をストップする時間
Pass 入力値をそのまま出力に渡す
Parallel 並列処理
Choice 条件分岐
Map 配列の要素ごとに処理を実行する
Fail 実行結果を失敗とする
Succeed 実行結果を成功とする

Taskの内容

フィールド 内容
Name Tags
Resouce URI/呼び出すサービスのARN
InputPath 値をStateに渡す
Parameters JSON形式でStateに値を渡す
ResultPath Stateの実行結果をどのようなフィールド名で受け取るかを指定する
OutputPath 次のStateに渡す値を指定する(未指定の場合、ResultPathの結果が採用される)
Retry Stateでランタイムエラーが発生した場合の再試行ポリシー
Catch 再試行ポリシーが使い果たされたか定義されていない場合に実行される処理
TimeoutSeconds 処理をタイムアウトさせる時間
HeartbeatSeconds ハートビートの間隔が指定した時間を超えた場合に失敗させる

ワークフロー

ステートマシンを作成する際、標準またはExpressのいずれかのワークフローの種類を選択します。
実行の動作や課金状態はそれぞれのワークフローで異なります。詳細は以下となります。

  • 標準ワークフロー:長時間実行され、耐久性がある。最大1年実行でき、実行完了から最大90日間、実行履歴を取得できる
  • Express ワークフロー:IoTデータの取り込みやストリーミングデータの処理など、大量のイベントを処理する必要のあるワークロード向き。実行可能時間は最大5分。

標準ワークフローとExpressワークフロー

連携できるAWSサービス

Step Functions ではLambda/DynamoDB/SNS/SQSなど、様々なサーバレス向けのサービスとの連携がサポートされています。
ASLに対象のリソースを指定することで、そのリソースから値や状態を取得することができます。
連携のパターンは以下です。

  • リクエストレスポンス:リソースに対してHTTP応答を要求する。Step Functions はジョブの完了を待たない。
  • ジョブの実行:AWS Batch や ECS との統合の場合にリクエストが完了するのを待ってから次のStateに進む。TaskのResouce指定時にARNの末尾に.syncをつける。
  • コールバックまで待機:リソースからタスクトークンが返されるまで処理を中断する。TaskのResouce指定時にARNの末尾に.waitForTaskTokenをつける。

それぞれ、対応しているサービスは以下となります。

Step Functions でサポートされるAWSサービス統合

Activity

Activityという機能を用いて、サーバーやコンテナ上に配置したアプリケーションをStep Functionsから呼び出すこともできます。

ステートマシンを呼び出す(実行する)方法

ステートマシンを実行するには、主に以下の方法があります。

やってみる

公式のチュートリアルを使って、実際に触ってみました。
今回使用したのはこちらです。
Create a 'first-to-respond' task request fanout pattern with Amazon SNS and AWS Step Functions

SNSを作成する

まず、SNSトピックを作成します。 SNSのマネジメントコンソールの左側メニューからトピックを選択し、トピックの作成をクリックします。

トピック名と表示名にDeliveryRequestと入力し、「トピックの作成」をクリックします。

トピック内にサブスクリプション(実際の送信先)を作成します。
作成したトピックを選択し、サブスクリプションの作成をクリックします。

プロトコルにEメールを選択し、エンドポイントに任意のメールアドレスを入力し、「サブスクリプションの作成」をクリックします。

入力したメールアドレス宛に承認依頼メールが届くので、「Confirm subscriprion」をクリックすると登録完了です。

Lambda関数を作成する

次にLambda関数を作成します。
「一から作成」を選択し、関数名にdriverSallyと入力し、「関数の作成」をクリックします。

関数の設定から「トリガーを追加」をクリックします。

トリガーにSNSを選択し、SNSトピックに先ほど作成したトピックを選択して「追加」をクリックします。

関数に、チュートリアル内のコードをペーストし、保存します。

Lambda関数を同じ手順でdriverAlexの名前で作成します。

IAMロールに権限を付与する

次に、Lambdaを定義した際に作成されたIAMロールに、Step Functions を操作するための権限を付与します。
IAMのマネジメントコンソールに移動し、先ほど作成されたロールを選択します。

「ポリシーをアタッチします」をクリックします。

AWSStepFunctionsFullAccessを選択し、「ポリシーのアタッチ」をクリックします。

Step Functions を作成する

いよいよStep Functions を作成します。

Step Functions のマネジメントコンソールに移動し、「ステートマシンの作成」をクリックします。

チュートリアル内のコードを定義の中にペーストします。
ワークフローの図の更新ボタンをクリックすると、定義に沿ったワークフローが作成されます。
このコードでは、最初にCheck Inventoryが実行され、Place CC HoldRequest Driverが呼び出されます。
引数には入力値がそのまま渡されています。
Request Driverのタスク内でSNSが「コールバックまで待機(.waitForTaskToken)」の状態で呼び出されます。
SNSからLambdaがキックされ、Lambda関数内でタイムアウトがなければDelivery Assigned to Driverが、タイムアウトが発生すればNotify Customer of Delayが呼び出され、処理が終了します。

作成できたら、「実行の開始」をクリックして、動作させてみます。

実行ウィンドウに入力オプションがあるので、入力値をjsonで記述します。

ビジュアルワークフロー上で処理がリアルタイムで表示され、ステータス、入力/出力値を確認することができます。

画面下部の実行履歴でもログが確認できます。

お片付け

作成したSNS、Lambda、Step Functions、IAMロールを削除すれば今回作成したリソースの削除完了です。

さいごに

AWS Step Functions をゼロから勉強してみました。
こういったサービスを触るのが初めてだったので最初の理解に時間がかかりましたが、とてもおもしろいサービスだなと思いました!
引き続き勉強していきたいと思います。

この記事がどなたかのお役に立てば幸いです。

以上、コンサル部@大阪オフィスのYui(@MayForBlue)でしたっ(`・ω・´)