Step FunctionsのStates.Format組み込み関数で文字列を作成する

States.Format組み込み関数は、タスクの入力とする文字列を作成することで、ステートマシンの設計の柔軟性があがる重要な機能でした。
2023.07.01

データアナリティクス事業本部の鈴木です。

Step Functionsの汎用操作用の組み込み関数であるStates.Formatを使うと、入力の値を使って新しく文字列を作成することができます。

Amazon States Languageの基本的な組み込み関数ではあるものの、あんまり使ったことがなかったので練習してみました。

やりたいこと

ステートマシンから別のサービスを呼び出す際に名前などのパラメータを、入力に対応した値に毎回変えたいことがありました。

例えば、ステートマシンからSageMakerのCreateModel APIを使ってモデルを作る際にモデル名が必要になりますが、ステートマシンの入力に渡した実行日や条件を表す値をサフィックスとして使えると便利ですよね。

やりたいことのイメージ

この値の埋め込みをするためには、入力した値を使っていいかんじに文字列を作ってくれる仕組みが必要ですが、調べたところ、組み込み関数であるStates.Formatを使うととても簡単に実現できそうでした。

一方で、Amazon States Languageをあまり使い慣れていなかったこともあって、練習のため実際に簡単なサンプルのステートマシンを作って動かしてみたので、試した操作をまとめてみました。

やってみる

Passステートの例

ステートマシンの作成

まずは一番簡単な例をと思い、Passステートで試してみました。

なお、開発者ガイドによるとPassステートは入力の変換に使うことも意図されているので、文字列の作成用のステートとして使ってもよいかもしれません。

Workflow Studioでぽちぽちとステートマシンを作成しました。

Passステートによる組み込み関数の利用

定義は以下のようにしました。ParametersStates.Format組み込み関数を使い、入力した値を{}-{}に埋め込むようにしました。

{
  "Type": "Pass",
  "End": true,
  "Parameters": {
    "param.$": "States.Format('{}-{}', $.input1, $.input2)"
  }
}

結果の確認

コンソールから以下の入力で実行しました。

{
  "input1": "value1",
  "input2": "value2"
}

Passステートの出力を見ると、確かに入力した値をテンプレートに入れて1つの文字列とできていました。

Passステートでの作成

タスクステートの例

ステートマシンの作成

タスクステートのParametersの場合も上手くいくか確認しました。

今回も、Workflow Studioでぽちぽちとステートマシンを作成しました。Step Functions StartExecutionタスクで別のステートマシンを実行します。

入れ子のステートマシンの呼び出し側の作成

Parameters内でStates.Formatを使って文字列を加工してみました。定義は以下のようになります。

なお、アカウントIDは試したAWSアカウントのアカウントIDが入っているところです。

{
  "Comment": "A description of my state machine",
  "StartAt": "Step Functions StartExecution",
  "States": {
    "Step Functions StartExecution": {
      "Type": "Task",
      "Resource": "arn:aws:states:::states:startExecution.sync:2",
      "Parameters": {
        "StateMachineArn": "arn:aws:states:ap-northeast-1:アカウントID:stateMachine:InnerStateMachine",
        "Input": {
          "param.$": "States.Format('{}-{}', $.input1, $.input2)",
          "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$": "$$.Execution.Id"
        }
      },
      "End": true
    }
  }
}

呼び出される側のステートマシンの定義は以下です。デバッグしたいだけなので、Passで特に何もせず、入力をそのまま出力します。

{
  "Type": "Pass",
  "End": true,
  "ResultPath": null
}

結果の確認

コンソールから以下の入力で実行しました。

{
  "input1": "value1",
  "input2": "value2"
}

呼び出される側のステートマシンの入力には、以下のように結合した文字列が渡っていることが確認できました。

入れ子のステートマシンでの結果

最後に

Step Functionsの汎用操作用の組み込み関数であるStates.Formatを使い、入力の値を使った文字列の作成を試してみました。

Passステートメントで文字列作成だけを行うこともできますし、ほかのAWSサービスを呼び出すステートのParametersでも使うことができました。

Passステートメントの活用ですが、個人的には、ステートマシンの最初の方のステートにて、共通で必要な文字列をまとめて作っておくと、どこで値が作成されているのか管理しやすい設計となるように思いました。

参考になりましたら幸いです。

補足

組み込み関数 - AWS Step Functionsのページにも注記がありますが、組み込み関数を使用するには.$ステートマシン定義のキー値を指定する必要があります。

.$ステートマシン定義のキー値を指定しない場合は、States.Format('{}-{}', $.input1, $.input2)のような文字列がそのまま出力されました。

上手く組み込み関数が動かないなと思ったときは、一度作成した定義が間違っていないか確認してみてください。

{
  "Type": "Pass",
  "End": true,
  "Parameters": {
    "param": "States.Format('{}-{}', $.input1, $.input2)"
  }
}

文字列として出てくる場合

そのた参考にした文献