AWS再入門ブログリレー2022 AWS Step Functions編
こんにちは、のんピ(@non____97)です。
当エントリは弊社コンサルティング部による『AWS 再入門ブログリレー 2022』の30日目のエントリです。
このブログリレーの企画は、普段 AWS サービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。
AWS をこれから学ぼう!という方にとっては文字通りの入門記事として、またすでに AWS を活用されている方にとっても AWS サービスの再発見や 2022 年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。
では、さっそくいってみましょう。今日のテーマは『AWS Step Functions』です。
AWS Step Functionsとは
AWS Step Functionsとは様々な処理を連結して管理ができるサーバーレスオーケストレーションサービスです。
Lambda関数や各種APIの実行の順序を制御して、ETLやバッチ処理など順序だって実行したい一連の処理を簡単に管理することができます。
どのような処理を行うかはAWSマネージメントコンソール上でワークフローという形式で可視化することが出来ます。処置と処理が連携しているところからジョブ管理システムのような印象を持つかもしれません。
こちらのワークフローはAWS Step Functions Workflow Studioで設計したものです。AWS Step Functions Workflow Studioについての詳細な説明は以下エントリをご覧ください。
また、AWS Step Functions Workflow StudioのようにワークフローはGUIだけではなく、CLIで管理も可能です。こちらのワークフローをASL(Amazon States Language)で表現すると以下のようになります。(長いので折り畳みます。)
ASLの例
{ "Comment": "A description of my state machine", "StartAt": "Lambda Invoke", "States": { "Lambda Invoke": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "OutputPath": "$.Payload", "Parameters": { "Payload.$": "$" }, "Retry": [ { "ErrorEquals": [ "Lambda.ServiceException", "Lambda.AWSLambdaException", "Lambda.SdkClientException" ], "IntervalSeconds": 2, "MaxAttempts": 6, "BackoffRate": 2 } ], "Next": "SNS Publish" }, "SNS Publish": { "Type": "Task", "Resource": "arn:aws:states:::sns:publish", "Parameters": { "Message.$": "$" }, "Next": "Choice" }, "Choice": { "Type": "Choice", "Choices": [ { "Next": "Map" } ], "Default": "Glue StartJobRun" }, "Map": { "Type": "Map", "Next": "Step Functions StartExecution", "Iterator": { "StartAt": "DescribeAlarms", "States": { "DescribeAlarms": { "Type": "Task", "End": true, "Parameters": {}, "Resource": "arn:aws:states:::aws-sdk:cloudwatch:describeAlarms" } } } }, "Step Functions StartExecution": { "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Parameters": { "StateMachineArn": "arn:aws:states:REGION:ACCOUNT_ID:stateMachine:STATE_MACHINE_NAME", "Input": { "StatePayload": "Hello from Step Functions!", "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$": "$$.Execution.Id" } }, "Next": "Parallel" }, "Parallel": { "Type": "Parallel", "Branches": [ { "StartAt": "DeleteFunction", "States": { "DeleteFunction": { "Type": "Task", "End": true, "Parameters": { "FunctionName": "MyData" }, "Resource": "arn:aws:states:::aws-sdk:lambda:deleteFunction" } } }, { "StartAt": "CopyObject", "States": { "CopyObject": { "Type": "Task", "End": true, "Parameters": { "Bucket": "MyData", "CopySource": "MyData", "Key": "MyData" }, "Resource": "arn:aws:states:::aws-sdk:s3:copyObject" } } } ], "Next": "Success" }, "Success": { "Type": "Succeed" }, "Glue StartJobRun": { "Type": "Task", "Resource": "arn:aws:states:::glue:startJobRun", "Parameters": { "JobName": "myJobName" }, "Next": "Choice 2" }, "Choice 2": { "Type": "Choice", "Choices": [ { "Variable": "$", "IsPresent": true, "Next": "Fail" } ], "Default": "Wait" }, "Wait": { "Type": "Wait", "Seconds": 5, "Next": "Success" }, "Fail": { "Type": "Fail" } } }
こちらのように定義はコードでも管理できるので、GitHubやCodeCommitなどのバージョン管理のサービスを使えば、CI/CDパイプラインを構築して、自動でデプロイするなんてことも可能です。実際にCodeCommitやCodeBuild、CodePipelineを使ってCI/CDパイプラインを構築した例は以下になります。
AWS Step Functionsで定義した一連の処理のまとまりをステートマシンと呼びます。そのため、「ステートマシンを実行する」というのはAWS Step Functionsで定義した一連の処理を実行するという意味になります。
また、AWS Step FunctionsはStandardとExpressの2種類があります。主な使い分けや特徴は以下の通りです。
Standard:
- 1回の実行に5分以上かかると予想される場合に選択する。
- 2,000/秒実行レート
- 毎秒 4,000 の状態遷移レート
- 状態移行ごとの価格設定
- 実行履歴と視覚的なデバッグを表示
- すべてのサービス統合とパターンをサポート
- 一般的なバッチ処理やETLなど
Express:
- 5分未満のワークフローで、1秒あたり100,000回の呼び出しが必要な場合に選択する。
- 100,000/秒実行レート
- ほぼ無制限の状態遷移レート
- 実行回数および実行期間ごとの価格
- Amazon CloudWatch に実行履歴を送信
- すべてのサービス統合とパターンをサポート
- マイクロサービスなど
StandardとExpressを組み合わせて、StandardのステートマシンからからExpressのステートマシンを呼び出すことも可能です。ジョブ管理システムで管理していたような処理をAWS Step Functionsに移行する場合は、ほとんどStandardを選択すると考えます。
AWS Step Functionsのメリット
このようなサービスに求められる機能はなんでしょう。
一連の処理をワークフローとして管理したいのであれば、例えば以下のような機能が必要だと考えます。
- 同期実行
- 並列実行
- 条件分岐
- ループ
- 待機
- リトライ
- 例外処理
- 実行結果の確認
- 異なるワークフロー間の連携
AWS Step Functionsは上で挙げた機能を全て実現できます。しかもサーバーレスなので、一般的なジョブ管理システムのようにサーバーの管理をする必要はありません。
こういった機能を手軽に、すぐに使用できるのは非常に魅力的ですね。
AWS Step Functionsでできないこと
ここで、「ジョブ管理システムはAWS Step Functionsに置き換えられるんじゃないか?」と思われるかもしれません。
しかし、AWS Step Functionsはジョブ管理システムではないので、ジョブ管理システムにあるような以下の機能は提供されていません。併せて背景や緩和策についても記載します。
- ワークフローの途中からの実行
- 処理が途中で失敗した場合、途中から再実行することはできない
- リトライする場合は、ワークフローの先頭の処理からやり直す事になる
- そのため、再実行されても問題ないように冪等性のある処理の組み方をする必要がある
- 参考 : サーバーレスにおけるべき等性の実装 (バッチ処理と分散トランザクション編) ~サーバーレスが気になる開発者に捧ぐ「べき等性」ことはじめ 第 4 回~ - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS
- カレンダーと連携した柔軟な実行
- AWS Step Functions単体ではスケジューリング機能はない
- 定期実行したい場合は、EventBridgeルールのCron式やRate式で表現する
- Cron式やRate式で表現し切れない祝日や組織特有のイベントなどの制御する場合はAWS Systems Manager Change Calendarと連携する
- 祝日だった場合、その前後の日付に実行タイミングをずらすといった機能は対応難易度が高い。
- 参考 : [AWS Step Functions] AWS Systems Manager Change Calendarと連携して定期実行処理のイレギュラーケースに対応してみた | DevelopersIO
AWS Step Functionsでできる処理
ここでAWS Step Functionsでできる処理 = Stateの種類を紹介します。
Stateの種類一覧は以下の通りです。
- Task
- Choice
- Wait
- Success
- Fail
- Parallel
- Map
Task
Taskは単一の処理を行うStateです。
Taskで設定可能な処理は各種AWSのAPIとActivityです。現在は200以上のAPIを呼び出すことが可能です。
ActivityはEC2インスタンスやオンプレミス環境で動作しているアプリケーションの制御するものです。詳細は以下エントリをご覧ください。
Choice
Choiceは条件分岐を行うStateです。
どのような条件の時に、どのStateに遷移させるか指定することができます。
指定可能な比較演算子は以下の通りです。
- And
- BooleanEquals,BooleanEqualsPath
- IsBoolean
- IsNull
- IsNumeric
- IsPresent
- IsString
- IsTimestamp
- Not
- NumericEquals,NumericEqualsPath
- NumericGreaterThan,NumericGreaterThanPath
- NumericGreaterThanEquals,NumericGreaterThanEqualsPath
- NumericLessThan,NumericLessThanPath
- NumericLessThanEquals,NumericLessThanEqualsPath
- Or
- StringEquals,StringEqualsPath
- StringGreaterThan,StringGreaterThanPath
- StringGreaterThanEquals,StringGreaterThanEqualsPath
- StringLessThan,StringLessThanPath
- StringLessThanEquals,StringLessThanEqualsPath
- StringMatches
- TimestampEquals,TimestampEqualsPath
- TimestampGreaterThan,TimestampGreaterThanPath
- TimestampGreaterThanEquals,TimestampGreaterThanEqualsPath
- TimestampLessThan,TimestampLessThanPath
- TimestampLessThanEquals,TimestampLessThanEqualsPath
Wait
Waitは指定された時間待機するStateです。
相対時間(秒数) と絶対時間 (タイムスタンプ) のいずれかを選択できます。
以下エントリでは相対時間と絶対時間のどちらかを指定して、指定した時間待機するような処理を実装しています。
Success
Successは正常終了をさせるStateです。
ワークフローの最後にSuccessを必ず追加する必要はありません。Choiceで条件分岐をした結果、何もせずにそのままステートマシンを終了させる場合に使用します。
Fail
Failは異常終了をさせるStateです。
Choiceで条件分岐をした結果、ステートマシンを異常終了させたい場合に使用します。
Parallel
Parallelは平行処理を制御するStateです。
2つ以上の処理を並行して実行したい場合に使用します。
Map
Mapは配列に対して繰り返し同じ処理を行うStateです。
例えば複数のEC2インスタンスを停止させたい場合は、EC2インスタンスIDの配列をMapに渡して、Map内でEC2:StopInstances
APIを実行するように定義すれば簡潔に表現できます。
ステートマシンの実行方法
ステートマシンの実行方法は主に以下の方法があります。
- マネージメントコンソール
- EventBridgeルール
- API Gateway
- API
- CLI
- SDK
おそらく多くの場合は、EventBridgeルール経由でステートマシンを実行するのではないかと考えます。APIのバックエンド処理として使用する場合は、API Gatewayから実行するようにすれば良さそうです。
値の入出力
各State間で値を連携したい場合は各種制御パラメーターを使って、どういった値を受け取るのか、受け取らないのかを制御することができます。
制御パラメーターは以下の通りです。
- InputPath
- 入力の一部をフィルタリングしてStatesに渡す
- OutputPath
- 出力の一部をフィルタリングして次のStateに渡す
- ResultPath
- 出力を元の入力を出力に追加
- Parameters
- Statesに渡す入力を指定
- ResultSelector
- 出力の結果を変換
制御パラメーターの詳細な動作は以下エントリとAWS公式ドキュメントが参考になります。
ロギングとモニタリング
ステートマシンの実行結果のモニタリング方法は主に以下があります。
- CloudWatch Logsに出力された各Stateの実行ログを確認する
- マネージメントコンソールから実行履歴を確認する
- X-Ray トレースマップから処理のタイムラインを確認する
- CloudTrailからAPI実行履歴を確認する
マネージメントコンソールから確認する場合、以下のように正常に処理できたStateは緑色になっています。
また、CloudWatchメトリクスで取得可能なAWS Step Functionsの実行メトリクスは以下の通りです。
メトリクス | 説明 |
---|---|
ExecutionTime | 実行のスタート時点から終了時点までの間隔 (ミリ秒単位)。 |
ExecutionThrottled | 調整済みの StateEntered イベントと再試行回数。 |
ExecutionsAborted | 中断または終了された実行の数。 |
ExecutionsFailed | 失敗した実行の数。 |
ExecutionsStarted | スタートされた実行の数。 |
ExecutionsSucceeded | 正常に完了した実行の数。 |
ExecutionsTimedOut | 何らかの理由でタイムアウトした実行の数。 |
AWS Step Functions気になるお値段
2022/3/16 時点 AWS Step Functionsの料金(東京リージョン)
Standardの場合は以下の通りです。
- 毎月 4,000 回までの状態遷移は無料 (12ヶ月間のAWS無料利用枠の期間とは別に)
- 状態遷移 1,000 回あたり $0.025
Expressの場合は以下の通りです。
- 100 万件のリクエストあたり 1.00USD
- リクエスト当たり 0.000001USD
- メモリの利用量と使用時間
- GB-秒あたり 0.00001667USD 最初の 1,000 時間 GB 時間 (GB-秒あたり 0.0600USD)
- GB-秒あたり 0.00000833USD 次の 4,000 時間 GB 時間 (GB-秒あたり 0.0300USD)
- GB-秒あたり 0.00000456USD それ以降 (GB-秒あたり 0.01642USD)
AWS Step Functionsざっくり振り返ってみた
AWS Step Functionsをざっくり振り返ってみたました。
AWSのAPIを直接呼ぶことができるようになって、かなり使いやすくなったサービスです。皆さんもぜひ楽しいAWS Step Functionsライフを満喫してください。
次回、3/17(木)は千葉 幸宏(チバユキ)の「AWS IAM」の予定です。興奮しますね。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!