Step Functions使ってみた
仕事でStep Functionsを利用することになり、既に別サービスが稼働しているため私用パソコン・個人AWSアカウントを用いて動作の確認をしてみました。
ソースコード一式
私のGitHubの下記リポジトリに保存しております。
設定や事前準備はsrc/README.md
を確認してください。
(AWS認証情報などは消しております)
aws-step_functions
作成したStep Functionsのワークフローは以下になります。
Step Functionsに関して調べたこと
※全体のソースコードはリポジトリを見て下さい。
▪️sam template.yamlとStep Functionsの定義ファイル(Amazon State Language)を分ける
template.yamlにStep Functionsのステートの設定(ワークフローの流れ)を
記載することができます。
ただ、template.yamlのコード数が増えリソースの定義以外も含めると
template.yamlの役割が複数になるため下記のファイル構成にしました。
・ビルドで利用するAWSリソースの定義ファイル(template.yaml)
・Step Functionsの定義ファイル(sfn.asl.json)
Step Functionsの定義ファイルとtemplate.yamlは
template.yamlのDefinitionUri
の部分で連携してます。
※参考サイト
https://blog.serverworks.co.jp/build-step-functions-state-machine-with-aws-sam-template
TestStepFunction:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: sfn.asl.json
▪️sam template.yamlとStep Functionsの定義ファイル(Amazon State Language)を連携する
Step FunctionsでLambdaを利用することは多いと思いますが、
template.yamlと連携しない場合はStep Functionsの定義ファイルに
LambdaのARN(リソースネーム)を直接設定する必要があります。
ただそれだと利便性が悪いためLambdaなどを定義するtemplate.yamlと
Step Functions定義ファイルを連携しました。
※参考サイト
https://blog.serverworks.co.jp/build-step-functions-state-machine-with-aws-sam-template
template.yamlのStep Functionsを記載している部分のDefinitionSubtitutions
の
キー名がsfn.asl.json
のResource
で変数として利用できます。
TestStepFunction:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: sfn.asl.json
DefinitionSubstitutions:
StateLambda1: !GetAtt StateLambda1.Arn
StateLambda2: !GetAtt StateLambda2.Arn
"States": {
"StateLambda1": {
"Type": "Task",
"Resource": "${StateLambda1}",
---- 省略 ----
"StateLambda2": {
"Type": "Task",
"Resource": "${StateLambda2}",
---- 省略 ----
▪️Lambdaの処理結果を次のLambdaに連携する
Step Functionsではワークフローを流れていくデータがある(とイメージしております。。)
そのため、そのデータにLambdaの処理結果をどのように追加するかを
sfn.asl.json
のResultPath
で設定しております。
※参考サイト
https://dev.classmethod.jp/articles/stepfunctions-parameters-inter-states/
"StateLambda1": {
"Type": "Task",
"Resource": "${StateLambda1}",
--- 省略 ---
"ResultPath": "$.result",
$
がワークフローを流れていくデータを指すことになります。
そのため$.result
ではLambdaの処理結果が以下のように追加されます。
{
result: Lambda処理結果オブジェクト
}
処理結果はreturn
したデータがresult
に格納されます。
この際にプリミティブ型をreturn
するとエラーになるため必ずオブジェクト形式にしてください。
▪️2つのLambdaで同一のResultPathを指定した場合
2つのLambdaのResultPath
が同じパスを指定している場合、
2つ目のLambdaがreturn
したときにデータは上書きされます。
リポジトリのLambdaでは1つ目のLambdaで$.result
に以下のデータを格納しております。
{
count: 2,
users: [
{
user_id: 1,
user_name: 'test1',
},
{
user_id: 2,
user_name: 'test2',
},
],
};
2つ目のLambdaの入力は上記になります。
2つ目のLambdaでは$.result
に以下のデータを格納しております。
{ count: event.result.count };
この場合、もし次のLambdaなどがあった場合、$.result
には以下だけになります。
{ count: event.result.count };
データの追加ではなくデータの上書きになります。
▪️Lambdaの処理ではなくPass
ステートでデータを上書きする
Lambdaを使用しなくてもワークフローを流れていくデータを上書き or 追加できます。
今回はPass
ステートで$.result
を上書きしてます。
Result
で設定したオブジェクト形式(JSON形式?)で
ResultPath
を上書きしてます。
"Call": {
"Type": "Pass",
"Result": {
"count": 0
},
"ResultPath": "$.result",
"Next": "Success"
}
▪️DefinitionUriの場所について
deploy
時にtemplate.yamlのStep FunctionsのDefinitionUri
の記載位置が原因でエラーとなりました。
Properties
のすぐ下にDefinitionUri
かDefinition
がないとエラーとなりました。
エラーコード
TestStepFunction:
Type: AWS::Serverless::StateMachine
Properties:
Name: TestStepFunction
DefinitionUri: sfn.asl.json
エラーメッセージ
Either 'Definition' or 'DefinitionUri' property must be specified Step Functions
deploy
できたコード
TestStepFunction:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: sfn.asl.json
色々なサイトを見てもProperties
にName
がありDefinitionUri
も設定しているので
なんでエラーメッセージでDefinition
or DefinitionUri
どっちか指定しろって
怒られてるんやろってなってました。。。
順番が大事なのか。。。
使ってみて
色々なサイトでStep Functionsの設定など記載がありましたが
基礎の基礎が逆に少なく、なぜその設定をしているのかが少なかったため
調べることに時間がかかりました。
この記事が未来の自分自身や
AWSほぼ触ったことないけど仕事で使うことになったから知りたいけどお金かかる不安やデプロイなどわからない人の
役に立つと幸いです。