こんにちは、西山です。
AWSのサービスを組み合わせて面白いものを作りたいと思った人は誰しも、AWS Step Functions(以下Step Functions)の存在を知ったときになんて素晴らしい神サービスだと思ったはずです(暴論)。
私もそんな一人ですが、Step Functionsをもっと使いたいのに使ってない!→ちゃんと理解できていないんじゃないかと感じていたため、改めて基本から学習し直すことにました。
今回はStep Functionsの基本となる概念について、いままでふわっと理解していた箇所も含めて様々な公式ドキュメントを読んだ結果をアウトプットしていきたいと思います。
本文中に参考リンクを載せているものもありますが、画像や文章の引用元は末尾の参考資料にまとめています。
目次
サービス概要
一言で言うとワークフローのサービスなのですが、業務フローをローコードで自動化するワークフローサービスではなく、サーバーレスアプリケーションのためのオーケストレーションサービスです。
Step Functionsはタスクを組み合わせてワークフローを作成しますが、それぞれのタスクはステートレスかつ別々のノードとして実行される分散コンピューティングアーキテクチャとなっています。サーバーレス開発を行うと複数のプロセスを組み合わせてユースケースを実現していくことになりますが、その各プロセスの条件分岐やループ、リトライ処理などを含めて検討し設計開発することはとても大変です。
Step Functionsは各プロセスをタスクとし、そのタスクをワークフローという形で条件分岐やループという形を含めてユースケース定義することで、タスクのオーケストレーションを行うサービスになります。
ざっくり表現で言うと、AWSのいろいろなサービスやロジックを組み合わせた処理全体をStep Functionsで一つのワークフローにまとめていい感じに実行してくれるという感じです。
API呼び出しや条件分岐などをアプリケーションロジックで全部書いてECSやLambdaで実行!というふうにすることもできるため、Step Functionsはローコード化するワークフローツールにも感じてしまいますが、その本質はワークフローのステート管理にあります。
APIでのAWSサービス呼び出しやアプリケーションロジックをタスクとして別プロセスに切り離すことによって、それぞれのプロセスをStep Functionsが管理しロギング、可視化してくれるためワークフローの中でどこまでがうまくいってどこで失敗したのか、並列プロセスでは並列実行の中のどこで失敗したのかといった部分をマネージドに行ってくれます。これを自前でアプリケーションの中でやろうとすると大変ですし、アプリケーションが大きくなるほどに単一障害点としてのリスクも大きくなります。
用語
用語 | 意味 |
ステートマシン | Step Functionsで作成するワークフローのこと。1ステートマシン = 1ワークフロー。 |
ステート | ステートマシン内の各要素をステートと呼びます。ステートには以下のようなタイプがあり、それらを組み合わせてステートマシンを作成します。
条件分岐:Choiceタイプのステート |
ASL(Amazon States Language) | ステートマシンを定義するための専用のJSONベースの言語です。 |
ワークフロータイプ
Step Functionsでまず知らなければならないのはワークフロータイプです。標準ワークフロータイプとExpressワークフロータイプの2種類があります。ワークフロータイプによって実行可能期間や料金体系、ステートマシンの実行方式も変わってくるため、しっかりと理解してユースケースに適したタイプを選択することが非常に重要になります。
それぞれのワークフロータイプの概要は以下のとおりです。
Expressワークフローには非同期呼び出しと同期呼び出しがあるため、Step Functionsでのワークフロータイプ選択は
- 標準ワークフロー
- Expressワークフロー(非同期呼び出し)
- Expressワークフロー(同期呼び出し)
の3つの中で考えることになります。
そして、それぞれのワークフローは以下のように実行されます。
標準ワークフロー
標準ワークフローは「Exactly-once」必ず一回実行するため、Amazon EMRクラスターの開始や支払いの処理など、冪等ではないアクションの調整に適しています。また、タスクステートの非同期実行やコールバック実行に対応しておりフロー全体が長時間実行する必要がある場合にはこちらを選ぶ形になります。
Expressワークフロー(同期呼び出し)
Express ワークフローのうち、ワークフローのレスポンスを待つことができ、エラーや再試行、並列タスクの実行のためのコードを追加することなくアプリケーションを開発したい場合は、同期呼び出しタイプのExpressワークフローが適しています。同期呼び出しは「At-most-once」最大で一回実行となっていますが、これはどういうことかと言うと、同期呼び出しタイプのExpressワークフローを実行中にTCP切断がおきた場合に、ステートマシンの実行が成功していようがしていまいが、ネットワークレベルの例外がスローされ、ステートマシンの実行が担保されない(1回実行したかもしれないし、していないかもしれない)ということです。また、ステートマシンの実行リクエストが成功したが、その後サーバーサイドでエラーが起きた場合(Step Functions自体の障害ケース)に、ステートマシンを自動で再実行しないようです。
アプリケーション実装観点で言うと、ワークフロー呼び出し元で正常なレスポンスを得られなかった場合にはリトライ処理を入れておけば問題ないということになります。もちろん、リトライを行うためワークフローは冪等性が担保されていなければいけません。
詳細は以下を参照してください。
At-least-once execution of AWS synchronous express step functions
Expressワークフロー(非同期呼び出し)
メッセージングサービスや他のサービスに依存しないデータ処理など、即時のレスポンスを必要としない場合は、非同期呼び出しタイプのExpressワークフローを利用します。
非同期呼び出しは「At-least-once」最低でも1回実行であるため、ワークフローは冪等性が担保されていなければいけません。
標準とExpressどちらを使えばよいか
標準ワークフローとExpressワークフローでどちらを使えばよいか迷った場合は、とりあえずExpressワークフローで実装を検討することを推奨します。
ワークフローの処理が5分を超える長時間であったり、冪等ではないわかりやすいユースケースの場合は標準ワークフローを選択しやすいです。
標準ワークフローとExpressワークフローのどちらでも実現できるユースケースの場合、Expressワークフローの方がコスト効率が高いためExpressワークフローが推奨されます。
ユースケース
Step Functionsのステートマシンの中で具体的にどういうことができるかというユースケースは以下になります。
④人間の承認フローを挟むことができる
⑤と⑥の違いは、⑤のParallelは一つの共通した入力データをそれぞれ別の処理を並列実行するというユースケースですが、⑥のMapは入力配列データから動的にデータを取得し、同じ処理を並列実行するというものです。いずれも並列に処理が実行されますが、⑤Parallelは一つのデータに対して異なる処理をしたい場合、⑥Mapは動的なデータにそれぞれに共通処理をしたい場合というふうに使い分けます。
各ユースケースの詳細説明は以下を参照してください。
また、MapのインラインモードとDistributed(分散)モードについては別ブログで取り上げたいと思います。
サービス統合
ユースケースには記載されていませんが、ステートマシンの中でTaskタイプのステートを利用することで、以下のサービス統合を実行することができます。AWSドキュメント上ではサービス統合は統合の種類を指すもので、次章のサービス統合パターンとの混同に注意です。
- アクティビティ
- サポートされている多数のAWSサービスのAPIコール(AWS SDK統合)
- 特定のAWSサービスの最適化された統合(最適化サービスの統合)
- サードパーティのAPIのHTTPコール
アクティビティ
Step FunctionsのActivityは実際に利用しているケースをあまり聞いたことがないです。
Step Functionsは各タスクをトリガーする、つまりpush型で実行しますが、特定のクラウド上のサービスまたはオンプレミスのサービスにおいては、直接トリガーすることができないケースがあります。
そういったアプリケーションをステートマシンに組み込む場合はこのアクティビティを利用します。アプリケーションがステートマシンのアクティビティ状態をポーリングし、ステートマシンがアクティビティタスクに達したらポーリングに対してレスポンスを返します。レスポンスをトリガーにアプリケーションを実行し、ステートマシンに実行結果を返すというものです。
実際の動作については以下を参照してください。
AWS Step Functions:Activity State MachineでLambda以外のアプリケーションを実行してみた
AWS SDK統合
Step FunctionsからはAWS SDK統合によって、ほぼすべてのAWSサービスのほぼすべてのAPIを実行することができます。
APIを実行し、APIコールに定義されているレスポンスが返されます。
ステートマシンのASLでは以下の構文で呼び出しをします。
1 |
arn:aws:states:::<span style="color: #ff0000;">aws-sdk</span>:serviceName:apiAction.[serviceIntegrationPattern] |
赤字のaws-sdk部分が、このあとの最適化サービスの統合との違いで重要になる点です。構文でaws-sdkが使われているということはAWS SDK統合を行っているということになります。
最適化サービスの統合
上記のAWS SDK統合でほぼすべてのAWSサービスと統合ができますが、一部のAWSサービスでは最適化された統合が行われており、例として以下のような実行を行うことができます。
- AWS Batch, AWS CodeBuildのジョブが完了するまでタスクが待機し、同期的にステートマシンを実行することができる
- Amazon DynamoDBのCRUD操作を行うことができる
- AWS Lambdaを同期、非同期で呼び出すことができる
最適化サービスの呼び出しは以下のようなaws-sdkを含まない構文で行います。
1 2 3 |
arn:aws:states:::codebuild:batchDeleteBuilds arn:aws:states:::dynamodb:getItem arn:aws:states:::lambda:invoke |
これらのサービスはaws-sdk込のAWS SDK統合でも実行することができますが、その場合は最適化された呼び出しにならないため注意が必要です。
最適化された統合をサポートしているサービス一覧は以下を参照してください。
最適化されたサービスと Step Functions の統合
HTTP APIコール
パブリックなHTTP APIを呼び出す統合もあります。
ステートマシンに認証情報がハードコーディングされることを防ぐために、EventBridge Connection、Secrets Managerを利用しての安全にAPIの認証を行うことができます。
サービス統合パターン
前章ではサービス統合の種類について説明しましたが、それとは別にサービス統合パターンというものがあります。
これは、統合されたサービスをどのように呼び出すか、その呼び出し方のパターンを指します。
統合パターンは以下の3つになります。
そして重要なことは、標準ワークフローと Express ワークフローは、同じ統合をサポートしますが、同じ統合パターン はサポートしないということです。
どちらのワークフローもアクティビティ、AWS SDK統合、最適化サービスの統合、HTTP APIコールをサポートしていますが、標準ワークフローはすべての統合パターンをサポートするのに対し。Expressワークフローはリクエストレスポンスのみをサポートします。
同期ポーリングもコールバックも非同期処理が終わるまで待機し必然的にある程度時間がかかる処理になるため、標準ワークフローを利用するのはしっくりきますね。
同期ポーリングとコールバックパターンを実行するには、呼び出しにおいてそれぞれ固定のサフィックスをつけるだけです。それぞれ同期ポーリング(.sync)、コールバック(/watForTaskToken)になります。
1 2 |
arn:aws:states:::batch:submitJob.sync arn:aws:states:::sqs:sendMessage.waitForTaskToken |
おわりに
一番重要なStep Functionsの基本概念をひと通りりおさらいしました。
今回のパートが理解できれば、ステートマシン設計やASLの書き方、タスクへの入出力処理といった実際に手を動かしていく部分はスムーズに進められるかと思います。
次回(未定)は実際にステートマシンを設計、開発していきたいと思います。
参考資料
AWS Black Belt Online Seminar AWS Step Functions
at most once, at least once, exactly once
Serverless Applications Lens – AWS Well-Architected Framework
- AWS Step Functionsの基本を再学習しました - 2024-09-23
- Amazon SESでバウンスメールを管理する - 2024-07-07
- TEAMをv1.1.1にアップデートしカスタムドメインを設定する - 2024-02-17
- コールセンター白書2023とAmazon Connect - 2023-12-25
- Provide dynamic and personalized CX with in-app web call for Amazon Connect - 2023-12-16