はじめに

Step Functionsが気になっている中、触る機会が訪れたので復習も兼ねて記事にさせていただきました。
本記事は特にChoicesステートを利用し条件分岐を行い、条件に合致する間はループ処理をするものとなります。

Step Functionsとは

以下がAWSドキュメントの抜粋となります。

AWS Step Functions は、デベロッパーが AWS のサービスを利用して分散型アプリケーションを構築し、プロセスを自動化し、マイクロサービスのオーケストレーション、データと機械学習のパイプラインを構築できるようにするビジュアルワークフローサービスです。

要するに、主にLambda関数の実行/待機/分岐/繰り返しなどの処理や様々なAWSサービスのAPI呼び出しのプロセスをステートマシンという中で順序や状態を定義しフローの自動化を行うことができます。

ループ処理とは

Step Functionsで定義した状態になるまで処理を続けたり、処理を終了したりする条件分岐を行わせます。
今回は以下のステートを使用します。

Choices
ステートマシンが次に移行する状態を決定する選択ルールの配列。選択ルールで比較演算子を使用して、入力変数を特定の値と比較します。例えば、選択ルールを使用すると、入力変数が 100 より大きいか小さいかを比較できます。

処理概要

今回はループ処理がわかりやすい様にLambdaは細かく分割させていただきました。

  1. インプットパラメータを送信する(手動)
  2. Step functionsでカウント変数の初期値0を挿入する
  3. Lambda-1でカウント変数の値がloopcountより小さい時にTrueフラグをつける、それ以外のときにFalseフラグをつける
  4. Step functionsでTrueフラグがある時に5に進む、Falseフラグがある時に8に進む
  5. Lambda-2で”Hello!!”を出力する
  6. Lambda-3でカウント変数に+1を行う
  7. 3の処理に戻る
  8. 処理完了

設定内容

ステートマシン

{
  "Comment": "Looping Example",
  "StartAt": "SetCount1",
  "States": {
    "SetCount1": {
      "Type": "Pass",
      "Result": 0,
      "ResultPath": "$.counter",
      "Next": "Lambda1"
    },
    "Lambda1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:[アカウントID]:function:lambda-sample-1",
      "Next": "ChoiceLoopState1"
    },
    "ChoiceLoopState1": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.continue",
          "StringEquals": "true",
          "Next": "Lambda2"
        },
        {
          "Variable": "$.continue",
          "StringEquals": "false",
          "Next": "ProcessComplete"
        }
      ],
      "Default": "ProcessComplete"
    },
    "Lambda2": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:[アカウントID]:function:lambda-sample-2",
      "Next": "Lambda3"
    },
    "Lambda3": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:[アカウントID]:function:lambda-sample-3",
      "Next": "Lambda1"
    },
    "ProcessComplete": {
      "Type": "Succeed"
    }
  }
}

lambda-sample-1

def lambda_handler(event, context):
    # カウント変数の値とloopcountの値を取得
    counter = event.get("counter", 0)
    loopcount = event.get("loopcount", 0)

    # カウント変数の値がloopcountより小さい場合は"true"、それ以外は"false"
    continue_flag = "true" if counter < loopcount else "false"

    # 結果を返す
    return {
        "continue": continue_flag
    }

lambda-sample-2

import json

def lambda_handler(event, context):
    output = "Hello!!"
    return {
        'output': output
    }

lambda-sample-3

import json

def lambda_handler(event, context):
    counter = int(event.get('counter', 0))
    counter += 1
    return {
        'counter': counter
    }

実行

ステートマシンの実行を開始より以下パラメータを入力します。

{
  "loopcount":3
}

実行結果

ちゃんと条件分岐によるループ処理が行われていました。
3回’output’:”Hello!!”が出力されました。
(今回はイベントにてloopcountの回数分処理が行われたことを確認しました)

まとめ

Lambdaの処理をLambdaに連携するなどといった、各処理の連携がStep Functionsを利用することで容易に実現できました。
またStep Functionsメニュー画面にグラフビューが自動で表示してくれたりと視覚的にとても便利だと感じました。
今回はJSONで定義を行いましたがデザインでステートマシンの定義をすることも可能です。
色々な処理を定義できそうで、とてもわくわくさせられるサービスですのでみなさんも一度触ってみることをおすすめします!