Step FunctionsステートマシンのContextオブジェクトにアクセスしてみた

2021.12.06

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

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、AWS Step FunctionsステートマシンのContextオブジェクトにアクセスしてみました。

Contextオブジェクトとは

Step FunctionsのContextオブジェクト(Context Object)を使用すれば、ステートマシン実行内でステートマシンの実行に関するコンテキストデータをJsonオブジェクトで取得できます。

取得できるContextオブジェクトを先にまとめると下記のようになります。

プロパティ(大) 説明 プロパティ(中) 説明
Execution ステートマシンの実行 Id 実行ID
Input 実行入力
StartTime 実行開始時間
Name 実行名
RoleArn 実行ロール
StateMachine ステートマシン Id ステートマシンID
Name ステートマシン名
State ステート Name ステート名
EnteredTime ステート開始時間
RetryCount ステート再試行数
Map マップ Item.Index 現在のアイテムのインデックス
Item.Value 現在のアイテムの値

これにより、ステートマシンの実行IDをタスク内で使用して後で追跡できるようにしたり、実行開始時間を別の処理に使えたりできるようになります。

やってみた

Contextオブジェクトにアクセスする

例として下記のようなステートマシンを作ってみました。Contextオブジェクトは$$でアクセスできます。

{
  "Comment": "A description of my state machine",
  "StartAt": "SNS Publish",
  "States": {
    "SNS Publish": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:sns:publish",
      "Parameters": {
        "Message": {
          "Context.$": "$$"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic"
      },
      "End": true
    }
  }
}

ステートマシンを実行します。

実行結果のTaskScheduledの出力を見てみます。

Contextプロパティ配下で$$からContextオブジェクトが取得できています。

{
  "resourceType": "aws-sdk:sns",
  "resource": "publish",
  "region": "ap-northeast-1",
  "parameters": {
    "Message": {
      "Context": {
        "Execution": {
          "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:execution:MyStateMachine2:f3daacd2-8397-bb5b-b7b0-ace372b4c2b7",
          "Input": {
            "Comment": "Insert your JSON here"
          },
          "StartTime": "2021-12-06T14:47:32.223Z",
          "Name": "f3daacd2-8397-bb5b-b7b0-ace372b4c2b7",
          "RoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/StepFunctions-MyStateMachine-role-f7ae852d"
        },
        "StateMachine": {
          "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:MyStateMachine2",
          "Name": "MyStateMachine2"
        },
        "State": {
          "Name": "SNS Publish",
          "EnteredTime": "2021-12-06T14:47:32.281Z",
          "RetryCount": 0
        }
      }
    },
    "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic"
  },
  "timeoutInSeconds": null,
  "heartbeatInSeconds": null
}

Contextオブジェクト内の個別のプロパティにアクセスする

次にContextオブジェクト内の個別のプロパティにアクセスしてみます。

{
  "Comment": "A description of my state machine",
  "StartAt": "SNS Publish",
  "States": {
    "SNS Publish": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:sns:publish",
      "Parameters": {
        "Message": {
          "ExecutionId.$": "$$.Execution.Id",
          "StateMachine.$": "$$.StateMachine",
          "StateEnteredTime.$": "$$.State.EnteredTime"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic"
      },
      "End": true
    }
  }
}

個別のプロパティにアクセスできました。

{
  "resourceType": "aws-sdk:sns",
  "resource": "publish",
  "region": "ap-northeast-1",
  "parameters": {
    "Message": {
      "StateMachine": {
        "Id": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:stateMachine:MyStateMachine2",
        "Name": "MyStateMachine2"
      },
      "StateEnteredTime": "2021-12-06T15:02:50.599Z",
      "ExecutionId": "arn:aws:states:ap-northeast-1:XXXXXXXXXXXX:execution:MyStateMachine2:9ad47ad2-f6ca-a41f-3838-b9313a60a3fd"
    },
    "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic"
  },
  "timeoutInSeconds": null,
  "heartbeatInSeconds": null
}

MapステートのContextオブジェクトにアクセスする

ここまでは実行内のどのステートからでもアクセスできるContextでしたが、Mapステート内でのみアクセスできるContextもあります。

例として下記のような定義のステートマシンを作成しました。MapステートのContextオブジェクトはMapステートのParameter内で$$.Mapでアクセスできます。またMapステートのParameterはMap内のステートのParametersで使用できます。

{
  "Comment": "A description of my state machine",
  "StartAt": "Map",
  "States": {
    "Map": {
      "Type": "Map",
      "ItemsPath": "$.mapped",
      "Parameters": {
        "Map.$": "$$.Map"
      },
      "Iterator": {
        "StartAt": "SNS Publish",
        "States": {
          "SNS Publish": {
            "Type": "Task",
            "Resource": "arn:aws:states:::aws-sdk:sns:publish",
            "Parameters": {
              "Message": {
                "Map.$": "$.Map"
              },
              "TopicArn": "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:testTopic"
            },
            "End": true
          }
        }
      },
      "End": true
    }
  }
}

以下の入力を使用してステートマシンを実行します。

{
    "mapped": [
		{
          "message": "おはようございます。"
    	},
		{
          "message": "おやすみなさい。"
    	}
    ]
}

するとMapステートの実行結果のTaskStateEnteredで、Contextオブジェクトが取得できています。

MapステートではItemsPathで渡した配列がマップ処理されます。$$.Mapにより配列内の各アイテムにアクセスできます。

{
  "name": "SNS Publish",
  "input": {
    "Map": {
      "Item": {
        "Index": 0,
        "Value": {
          "message": "おはようございます。"
        }
      }
    }
  },
  "inputDetails": {
    "truncated": false
  }
}

以上