Stepで覚えるStepFunctions基本のキ
はじめに
瀬田@大阪オフィスです。StepFunctions使ってますか?最初に想像していたよりめっちゃ便利&簡単なんで基本をご紹介したい欲。
今回の構成
こんな感じのやつを作ってみます。
テスト用lambda関数
Pythonで以下のようなlambda関数:testを作成します。
def lambda_handler(event, context): event["Result"] = True #項目はeventに任意に追加可能です。 event["LoopCount"] = 10 return event
ステートマシン定義
Step1:Exec lambdaの実行
lambdaを実行するStepを作成します。 コメント部は空白を含めて削除してください。(行末に空白があるとエラーになります。) lambdaのarnは適宜書き換えてください。
{ "Comment": "", #自由書式のコメント "StartAt": "Exec", #開始点 "States": { "Exec": { #Stepの動作定義開始 "Comment": "実行", #自由書式のコメント "Type": "Task", #実行タイプ "InputPath":"$", #StepFunctionを起動した時に取得した引数(CloudWatchEvents等から渡せる) "Resource": "arn:aws:lambda:ap-northeast-1:99999999999:function:test", #実行するリソースARN。InputPathの引数はlambda内のeventで取得可能。 "ResultPath":"$", #実行したソースからの戻り値を次の処理に渡す。 "End": true } } }
これを入力すると以下して、ステートマシン表示部のリロードボタンを押すと、以下のようになります。
Step2:ErrorCheck 結果の受け取りと分岐
前段の結果を受け取り、処理を分岐します。分岐先は両方とりあえず、最後の結果送信処理へ流します。lambdaからの返り値は$に入っています。
{ "Comment": "", "StartAt": "Exec", "States": { "Exec": { "Comment": "実行", "Type": "Task", "InputPath":"$", "Resource": "arn:aws:lambda:ap-northeast-1:99999999999:function:test", "ResultPath":"$", "Next": "ErrorCheck" #"End": true削除 }, #,追記 #----STEP追記---- "ErrorCheck": { #Stepの名称 前段の出力結果で分岐処理 "Type" : "Choice", #分岐処理 "Choices": [ { "Variable": "$.Result", #前Stepの処理結果が$に渡っているので、自分で定義した$.Resultを確認 "BooleanEquals": true, #条件判定 "Next": "SendResult" #次のStep名 }, { "Variable": "$.Result", #同上 "BooleanEquals": false, "Next": "SendResult" } ], "Default": "SendResult" #条件一致しない場合の遷移先Step }, #----STEP追記---- "SendResult": { #Stepの名称 最後に実行する処理を定義 "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:9999999999:function:test", "InputPath": "$", "End": true } } }
こんな感じ。
Step3:StateCheck 状態チェックとループ
前段の結果を受け取り、対象の状態がTrueになるまで待機させます。
{ "Comment": "", "StartAt": "Exec", "States": { "Exec": { "Comment": "実行", "Type": "Task", "InputPath":"$", "Resource": "arn:aws:lambda:ap-northeast-1:99999999999:function:test", "ResultPath":"$", "Next": "ErrorCheck" }, "ErrorCheck": { "Type" : "Choice", "Choices": [ { "Variable": "$.Result", "BooleanEquals": true, "Next": "StateCheck" #実行チェックに成功したらStepステータスチェックに移行 }, { "Variable": "$.Result", "BooleanEquals": false, "Next": "SendResult" #実行チェックに失敗したらエラーとして処理終了 } ], "Default": "SendResult" }, "SendResult": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:9999999999:function:test", "InputPath": "$", "End": true }, #,追記 #----STEP追記---- "StateCheck": { #Step:ステータスチェック "Type": "Task", "InputPath":"$", #前段の返り値受け取り "Resource": "arn:aws:lambda:ap-northeast-1:9999999999:function:test", "ResultPath":"$", #実行したソースからの戻り値を次の処理に渡す。 "Next": "Loop" #lambdaのチェック結果を取得して、Step:Loopに移行 }, #----STEP追記---- "Loop": { #Step:Loop処理 "Type": "Choice", "Choices": [{ "Or":[{ #Loopを抜ける判定をORでしてみる。 "Variable": "$.Result", #前段の出力がTrueだったら、 "BooleanEquals": true },{ "Variable": "$.LoopCount", #またはループ回数が10回以上であれば "NumericGreaterThanEquals": 10 }], "Next": "SendResult" #上記条件を満たした時の遷移先Step }], "Default": "Wait" #条件を満たさなければStep:Waitへ遷移 }, #----STEP追記---- "Wait": { #Step:待機処理 60秒スリープ "Type": "Wait", "Seconds": 60, "Next": "StateCheck" } } }
以下のようになり、完成しました。
実行
実行してみると、動いてますね。
以下がそのまま貼り付けて動くコードです。(lambdaのARNは変更してください。)
{ "Comment": "", "StartAt": "Exec", "States": { "Exec": { "Comment": "実行", "Type": "Task", "InputPath":"$", "Resource": "arn:aws:lambda:ap-northeast-1:99999999:function:test", "ResultPath":"$", "Next": "ErrorCheck" }, "ErrorCheck": { "Type" : "Choice", "Choices": [ { "Variable": "$.Result", "BooleanEquals": true, "Next": "StateCheck" }, { "Variable": "$.Result", "BooleanEquals": false, "Next": "SendResult" } ], "Default": "SendResult" }, "SendResult": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:99999999:function:test", "InputPath": "$", "End": true }, "StateCheck": { "Type": "Task", "InputPath":"$", "Resource": "arn:aws:lambda:ap-northeast-1:99999999:function:test", "ResultPath":"$", "Next": "Loop" }, "Loop": { "Type": "Choice", "Choices": [{ "Or":[{ "Variable": "$.Result", "BooleanEquals": true },{ "Variable": "$.LoopCount", "NumericGreaterThanEquals": 10 }], "Next": "SendResult" }], "Default": "Wait" }, "Wait": { "Type": "Wait", "Seconds": 60, "Next": "StateCheck" } } }
最後に
lambdaで処理遷移を考えることを思えば格段に楽チンですね。GUIでシュシュっと作れたらもっと楽しくなると思うのでアップデートに期待しています。