[アップデート]Step Functions ステートマシンのネストが可能になりました!

Step Functionsにアップデートがあり、ステートマシンのネストが可能になりました!

これにより、上位/下位でワークフローを分離でき、モジュールのように再利用可能になります。また、複雑さの軽減も期待できると思います。

早速試してみたいと思います。

構成

ここでは2つのステートマシンを用意します。以下の様なイメージです。

ステートマシン作成

下位ステートマシン

下位ステートマシン「LowerStatemachine」を作成します。特に新しいフィールド等はありません。ここではインプットにより終了ステータスが変化するように定義しました。

ステートマシンの定義は以下となります。

{
  "StartAt": "IsLowerSucceed",
  "States": {
    "IsLowerSucceed": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.lower_flg",
          "StringEquals":"Success",
          "Next": "SuccessState"
        }
      ],
      "Default": "FailState"
    },
    "SuccessState": {
      "Type": "Succeed"
    },
    "FailState": {
      "Type": "Fail"
    }
  }
}

上位ステートマシン

上位ステートマシン「UpperStatemachine」を作成します。下位ステートマシンを呼び出すシンプルなワークフローです。

ステートマシンの定義は以下となります。

{
  "StartAt": "Start LowerStatemachine",
  "States": {
    "Start LowerStatemachine": {
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync",
      "Parameters": {
        "StateMachineArn": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:LowerStatemachine",
        "Input": {
          "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$": "$$.Execution.Id",
          "lower_flg.$": "$.lower_flg"
        }
      },
      "End": true
    }
  }
}

ここではResourceフィールドでリソースURIの後に.syncを付与し、同期(実行の完了を待機)呼び出しにしました。 他にも非同期呼び出しや、.waitForTaskTokenでコールバックを受信するまで処理を停止させることも可能です。

また、Parametersフィールド内のInputにて、AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_IDという特別なパラメータを渡しています。これは、上位ステートマシンと下位ステートマシンの関連付けるために必要となります。

なお、ステートマシンに付与するロールはStep Functionsのコンソールにて生成しました。

生成されたロールのポリシーを確認すると、下位ステートマシン(LowerStatemachine)、CloudWatch イベントの操作権限が付与されていました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "states:StartExecution"
            ],
            "Resource": [
                "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:LowerStatemachine"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "states:DescribeExecution",
                "states:StopExecution"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "events:PutTargets",
                "events:PutRule",
                "events:DescribeRule"
            ],
            "Resource": [
                "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule"
            ]
        }
    ]
}

動作確認

上位ステートマシンを実行し、動作を確認してみたいと思います。

成功

終了ステータスが成功になるよう、以下を入力して実行します。

{
  "lower_flg": "Success"
}

想定通り、成功で終了しました。実行イベント履歴より下位ステートマシンに遷移ができます。

下位ステートマシンでは、呼び出し元の実行IDが確認できました。また、入力では上位ステートマシンで定義したAWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_IDにより、実行IDが下位ステートマシンの入力となっていました。

失敗

終了ステータスが失敗になるよう、以下を入力して実行します。

{
  "lower_flg": "Fail"
}

想定通り、失敗で終了しました。下位ステートマシンの結果により、Start LowerStatemachineステートが失敗になり、上位ステートマシンが終了しました。

下位ステートマシンは以下の状態です。

ちなみに、CloudWatch メトリクスもステートマシン毎に出力されていました。

補足:上位/下位の関連付けとは?

上位ステートマシン「UpperStatemachine」からAWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID定義を除いて動作確認してみました。

{
  "StartAt": "Start LowerStatemachine",
  "States": {
    "Start LowerStatemachine": {
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync",
      "Parameters": {
        "StateMachineArn": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:LowerStatemachine",
        "Input": {
          "lower_flg.$": "$.lower_flg"
        }
      },
      "End": true
    }
  }
}

この状態で実行したところ、以下のような結果となり、下位ステートマシンから呼び出し元の実行IDを確認することができなくなりました。(関連付けが何を指しているのかわかりました!)

最後に

今回のアップデートにより上位/下位でワークフローを分離でき、ステートマシンをモジュールのように再利用可能になると思います。複雑さが軽減され、Step Functionsでの開発が捗りますね!どんどん便利になっていくStep Functionsから目が離せません!

参考