この記事について
以前 AWS Step Functions を利用した処理を構築する機会があり、その時の備忘録としてまとめました。
Step Functions 自体は様々な処理をステート区切りで実行できるためかなり便利ではあるのですが、いざ複雑なことをしようとすると知識を要求される場面が多くなります。
そういったところを考慮して、この記事は初めて Step Functions に触れるという方を主な対象としています。
概要・目的
Step Functions では、ワークフロー定義(ASL: Amazon States Language)の記述言語として JSONata(jsonのクエリ言語) を使用できます。
Step Functions は JSONata 以外にも JSONPath の利用も可能ですが、JSONata は2024年11月からサポート開始されたのでナレッジが少なく苦労したため、今回は前者についてのみまとめていきます。
このガイドでは、JSONata モードにおける 変数の扱い方 に絞って基本的な知識を整理します。具体的には次の点を理解することを目標とします。
- 組み込み変数の使い方
- ステート間でデータを受け渡す方法
-
Assignを使った変数管理
JSONata モードは従来の JSONPath モードと比べて表現力が高い反面、独自の記法があるため、最初に「どこに何を書けばデータが流れるか」を把握することが重要です。
対象者
- AWS Step Functions を使い始めたばかりの方
- JSONPath モードは触ったことがあるが、JSONata モードは初めての方
- ワークフロー上の入出力がわかりにくい方
以下の前提知識があると読みやすくなります。
- AWS マネジメントコンソールでステートマシンを作成した経験(初歩レベルで可)
- JSON の基本的な読み書き
使い方
1. JSONata モードの有効化
ステートマシン定義のトップレベル、または個々のステートに "QueryLanguage": "JSONata" を追加することで有効になります。ステートマシン全体への指定と、ステート個別への指定が混在させることも可能です。
※ただし、可読性が下がるため非推奨
次以降では Pass という何もしないステートを1つ以上実行するワークフローを参考に、変数の使い方を例示しています。
{
"Comment": "A description of my state machine",
"StartAt": "state01",
"States": {
"state01": {
"Type": "Pass",
"End": true
}
},
"QueryLanguage": "JSONata"
}
2.テストと各ステートの出力
2-1.テスト状態
Step Functions コンソール自体の基礎的な使い方の話になるのですが、「他の開発ツールみたいなデバックモード、処理中の変数表示とかないの?ほんとに渡されてるの?」と確認したい場合もあると思います。そんな人の為に各ステートのデバックと出力を確認する機能もあります。
デバックには各ステートを対象に動作確認を実施するテスト機能があります。Step Functions 作成コンソールの画面右上の「テスト状態」というボタンを押下すると以下のような画面が表示されます。
各入力及び出力フィールドの内容は次の通りです。

| フィールド | 内容 |
|---|---|
| 状態の入力 | テスト対象としたいステートへの入力を記述する |
| 変数 | ワークフローが利用する変数の値を記述する |
| 状態の出力 | テストの対象としたステートの出力が表示される(記述はしない) |
| 変数 | テストの対象としたステートで定義した変数が表示される(記述はしない) |
詳細な利用例は後述の項で示しますが、このテスト状態という機能ではそのステートが実際に動いた場合にどのような出力、及び変数がそのワークフロー上に残るかを、テスト・動確することが出来ます。
2-2.ワークフロー実行上の出力
先の"テスト状態"では各ステート毎に独立した入出力のテストを実行することが出来ました。ですが、ワークフローを通しで実行した場合はどのようなデータフローとなっているのか確認したいと思うこともあると思います。
その場合は実際にワークフローを実行した後に表示される実行結果画面の下部にある、"イベント"タブより参照可能になっています。
各IDは開くことが可能になっており、各ステートでの実行状態が json 形式で記載されています。

3. データの流れと $states 変数
JSONata モードでは、現在のステートに渡されたデータや実行コンテキストは $states という組み込みオブジェクトから参照します。主なフィールドは次のとおりです。
| フィールド | 内容 |
|---|---|
$states.input |
現在のステートへの入力(前ステートの出力が入る) |
$states.result |
リソース(Lambda 等)の実行結果 |
$states.context |
実行メタデータ(実行 ID、ステート名など) |
JSONata 式の中ではフィールド.変数名と記述することで参照することが可能となり、動的にデータを取り出したり加工したりできます。
式の中で参照する場合は、対象の項目に{% ... %}とすることで変数を利用することが可能です。
以下の例の場合、state02に渡される$state.input.valueの値はHello Worldになります。
{
"Comment": "A description of my state machine",
"StartAt": "state01",
"States": {
"state01": {
"Type": "Pass",
"Next": "state02",
"Output": {
"value": "Hello World"
}
},
"state02": {
"Type": "Pass",
"End": true,
"Assign": {
"value": "{% $states.input.value %}"
}
}
},
"QueryLanguage": "JSONata"
}
例として先に説明したテスト機能で state01 を対象にテストした場合、以下の結果が得られます。
Outputに記載したため、狙い通り"状態の出力"にvalue = Hello Worldが表示されていることが確認できます。

また state02 を対象にテストした場合は以下の結果になります。
テストは対象のステートのみの実行となるため、"状態の入力"に前ステート state01 の出力を記述してあげる必要があります。
実行の結果、"変数"欄に$states.input.valueで参照した前ステートの出力を表示していることが確認できます。

このワークフローを実行した結果より、"イベント"タブも確認してみました。
state01 の output に記述した通り state02 の input にHello Worldが流れていることが確認できます。

4. Assign でフロー内変数を定義する
ステートからリソース(Lambda 関数など)を呼び出す際、渡す引数を JSONata 式で組み立てるには Assign フィールドを使います(JSONPath モードの Parameters に相当)。
値を JSONata 式として評価させる場合も、文字列として {% ... %} で式を囲みます。
利用する場合は、先に説明した形式フィールド.変数名ではなく 変数名 のみで参照可能です。(以下の場合$value)
{
"Comment": "A description of my state machine",
"StartAt": "state01",
"States": {
"state01": {
"Type": "Pass",
"Assign": {
"value": "Hello World"
},
"End": true
}
},
"QueryLanguage": "JSONata"
}
試しにこちらのフローもテストした結果、以下の通りになります。
実行の結果、"変数"欄にステート内で定義している値が格納されていることが確認できます。

このワークフローを実行した結果より、"イベント"タブも同様に確認してみましょう。
state01 の出力として、変数項目"assignedVariables"にHello Worldが確認されていることが確認できます。

まとめ
変数の使い方の基礎のみをまとめた形にはなりますが、何にも知らない時分に「来週までに Step Functions の設計お願いね」と頼まれた場合にでも活用してもらえれば幸いです。
その他、本記事でまとめた内容以上に関連URL先でまとめられているような JSONata 固有の関数などもあるので、それらを存分に活用するステップにでもしてください。
また今回は主題から外れるため省きましたが、テストの実行までであれば、AWS Toolkit でAWSアカウントと接続した VS Code からも開発、検証が容易に行えるようになります。