AWS Step FunctionsのChoiceステートではEndフィールドを使用できない

Choiceからすぐにステートマシンを終了させたい場合はPassステートを使おう!
2020.04.13

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

AWS Step Functionsで条件分岐(Choiceステート)があるステートマシンを作成しようとしたときに、Choiceステート内でEndフィールドを使用できなかったので他の方法を探してみました。

Choiceステート内でEndフィールドを指定したらエラーとなった

Step Functionsで以下のようなフローのステートマシンを作ろうとしました。

  1. ステートマシンを開始する(開始
  2. Lambdaを実行して戻り値を取得する(処理1
  3. 処理1の戻り値をもとに条件分岐する(条件分岐
    1. Trueなら終了に進む
    2. Falseなら処理2に進む
  4. Lambdaを実行して戻り値を取得する(処理2
  5. ステートマシンを終了する(終了

そこで以下のようなJSON定義を作成しました。条件分岐ではChoiceステートを利用して条件に一致する場合はステートマシンを終了(Endフィールドにtrueを指定)し、そうでない場合は処理2に進む(Defaultフィールドに処理2を指定)処理としています。

{
  "StartAt": "処理1",
  "States": {
    "処理1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:test",
      "Next": "条件分岐"
    },
    "条件分岐": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.key1",
          "BooleanEquals": true,
          "End": true
        }
      ],
      "Default": "処理2"
    },
    "処理2": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:test2",
      "End": true
    }
  }
}

しかし、このJSON定義をAWSコンソールのステートマシンの作成ページのエディターに貼り付けてみると、Choice処理の部分が以下のようにエラーとなりました。 image.png

上側のバツ印にマウスオーバーするとThese fields are required: Nextとメッセージが出ています。 image.png

下側のバツ印にマウスオーバーするとField End is not supportedとメッセージが出ています。 image.png

この状態だと当然ステートマシンは保存できず正常に動作させることもできません。

ダミーのPassステートを使ったら上手くいった

AWSのStep Functionsのドキュメントの「Choiceステート」ページを読んでみると以下のようにありました。

Choice states don't support the End field. In addition, they use Next only inside their Choices field.

ChoiceステートのChoicesフィールドの内部では、Endフィールドはサポートしておらず、Nextしか使えないとはっきり書いてありますね。先ほどのJSON定義はこの仕様に反していたためエラーとなっていたようです。

しかし、条件分岐でTrueとなる場合はステートマシンを終了させる以外の処理は不要のため、Nextフィールドを使うにしてもその後続処理では何もさせたくありません。

そこで便利なのがPassステートです。ドキュメントの「Passステート」ページを読んでみると

A Pass state ("Type": "Pass") passes its input to its output, without performing work. Pass states are useful when constructing and debugging state machines.

とあり、Passステートはinputをそのままoutputするだけの「何もしない」をするステートとのことです。なので基本的な用途はステートマシン作成時のデバッグ用となります。

今回はこのPassステートの「何もしない」仕様を利用します。ChoiceステートのEndフィールドにPassステートダミーを指定し、ダミーEndフィールドにtrueする以下のようなJSON定義とすれば、要望通りのステートマシンを作ることができました。

{
  "StartAt": "処理1",
  "States": {
    "処理1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:test",
      "Next": "条件分岐"
    },
    "条件分岐": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.key1",
          "BooleanEquals": true,
          "Next": "ダミー"
        }
      ],
      "Default": "処理2"
    },
    "処理2": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:test2",
      "End": true
    },
    "ダミー": {
      "Type": "Pass",
      "End": true
    }
  }
}

最終的に作成したステートマシンのフロー図。

image.png

おわりに

Choiceステートで、何もさせずにすぐにステートマシンを終了させる条件分岐を作りたい時はPassステートを使えばいいよ!というTipsでした。

余談ですがフロー図の作成は https://app.diagrams.net/ というサイトを利用しましたがとても便利でした。

参考

以上