Step FunctionsからAWS Batchの配列ジョブを実行してみる – パラメータの渡し方 #reinvent
re:Invent 2018において、Step Functionsから新たに8つのサービスが連携可能になったことが発表されました。
[神アップデート]Step Functionsが新たに8つのマネージドサービスと連携可能になりました! #reinvent
実際にこれを使っていくにあたっては、連携先のサービスに対してより細かい制御を行うため、Step Functionsから各サービスへパラメータを渡す必要があります。 その具体的な方法について、AWS Batchの配列ジョブを動かしながら試してみました。 詳細は公式ドキュメントの以下ページ配下に記載されています。(現在はまだ英語です)
パラメータの渡し方
Pass Parameters to a Service API
各サービスへ渡すパラメータは、各タスクのStateの"Parameters"で指定します。以下はSNSへ渡すパラメータを指定する例です。
"Resource": "arn:aws:states:::sns:publish", "Parameters": { "TopicArn": "arn:aws:sns:us-east-1:123456789012:myTopic", "Message": "test message", "MessageStructure": "json", "MessageAttributes": { "my attribute no 1": { "DataType": "String", "StringValue": "value of my attribute no 1" }, "my attribute no 2": { "DataType": "String", "StringValue": "value of my attribute no 2" } } },
前タスクの入力を渡したい場合はJsonPath形式で指定します。
その際、パラメータ名の末尾に.$
をつけます。例えばMessage
というパラメータに入力データの$.input.message
を渡したい場合は、以下のようになります。
"Parameters": {"Message.$": "$.input.message"},
Step Functionsから指定できるパラメータはサービスごとに決まっています。 詳細はこちらのドキュメントに記載されています。
補足・制限事項
- 各サービスへ渡すパラメータ名の先頭は大文字です。例えばAWS BatchのArrayPropertiesのSizeを指定するとき、小文字にすると以下のように怒られます。ドキュメントに小文字で書いてあるので少しハマりました。
- JsonPath形式で扱える入力・出力の値は文字列に限られるようです(リファレンス)。例えばArrayPropertiesのSizeは数値のため、JsonPath形式の値を指定することはできません。 *1
やってみた
実際にStep FunctionsからAWS Batchへパラメータを渡してみます。まず、以下の記事で紹介されているサンプルプロジェクトを構築します。
[新機能] AWS Step FunctionsがAWS BatchとSNSに連携可能となったのでさっそく試してみた #reinvent
このサンプルプロジェクトのBatchジョブはecho Hello world
を行うだけの簡単なものですが、これを少し変更してみます。
概要
例えば、何らかのIDのリストを取得してきて、それらに対して並列に何らかの処理を行う、といったバッチ処理を行うケース *2をイメージして、以下のような変更を加えてみます。
- AWS Batchの前に、IDのリストを出力するLambda関数を追加します。
- これはJSON文字列
{"statusCode": 200, "body": {"idlist": "a,b,c,d,e"}}
を出力します。
- これはJSON文字列
- Lambda関数が出力するIDのリストをAWS Batchのパラメータに渡し、それを配列ジョブで並列に処理します。
- 今回はとりあえず、各ジョブは受け取ったidlistをそのまま出力するだけです。
手順
まず、IDのリストを出力するLambda関数を作成します。
次に、これを処理するAWS Batchのジョブ定義を修正し、コマンドを以下のように変更します。
Ref::idlist
というのはAWS Batchでパラメータ置換を行う記法で、Parametersのキーidlistで指定された値に置換されます。
echo idlist: Ref::idlist
最後に、ステートマシンの定義を以下のように変更します。
- Lambda関数getIdListを実行するState "Get ID List"を"Submit Batch Job"の前に追加
- StartAtを"Get ID List"に変更
- AWS BatchのState "Submit Batch Job"の以下を変更
- JobDefinitionの末尾を修正後のリビジョンに変更
- ArrayPropertiesを追加
- Parametersを追加。"idlist"にLambdaの出力を渡す。
- Lambda関数を追加したので、その実行権を追加したIAMロールを作成します
- 画面下の"実行の IAM ロール"で"自分用のIAMロールを作成する"を選択
修正後のステートマシンの定義は以下のようになります。
{ "Comment": "An example of the Amazon States Language for notification on an AWS Batch job completion", "StartAt": "Get ID List", "TimeoutSeconds": 3600, "States": { "Get ID List": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:getIdList", "Next": "Submit Batch Job" }, "Submit Batch Job": { "Type": "Task", "Resource": "arn:aws:states:::batch:submitJob.sync", "Parameters": { "JobName": "BatchJobNotification", "JobQueue": "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxx:job-queue/BatchJobQueue-7bf649924d554dd", "JobDefinition": "arn:aws:batch:ap-northeast-1:xxxxxxxxxxxx:job-definition/BatchJobDefinition-8c71e1e40c37c60:17", "ArrayProperties": { "Size": 5 }, "Parameters": { "idlist.$": "$.body.idlist" } }, "Next": "Notify Success", "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "Notify Failure" } ] },
実行結果
AWS Batchのダッシュボードから成功したジョブの結果を確認できます。さらに個別のジョブのログをCloudWatch Logsで確認できます。
さらに個別のジョブのログをCloudWatch Logsで確認できます。
まとめ
Step FunctionsからAWS Batchの配列ジョブを動かしてみました。 今回のアップデートで様々なサービスを直接連携でき、パラメータも直接渡せるようになったので、複雑な処理も構築しやすくなったと思います。