ããã¯ããªã«ãããããŠæžãããã®ïŒ
LocalStackãAWS Step Functions Localã䜿ã£ãŠãAWS Step Functionsã®ãã¥ãŒããªã¢ã«ãç°å¢æ§ç¯ã詊ããŠããŸããã
ä»åºŠã¯ãç·Žç¿ãšããããšã§å ¥åºåãæ±ãAWS Lambda颿°ãæžããŠã¿ãããšæããŸãã
ãé¡
ããããå ¥åãäžãããš
{ "message": "Hello World" }
ãããªã£ãŠ
{ "result": "â â â Hello Worldâ â â ", "message": "â â â Hello Worldâ â â ", "inputOriginalMessage": "Hello World", "withStar": { "result": "â â â Hello Worldâ â â " } }
æåŸã«ãããªãã¯ãŒã¯ãããŒãçµãã§ã¿ãããšæããŸãã
{ "result": "***â â â Hello Worldâ â â ***", "inputOriginalMessage": "Hello World", "withStar": { "result": "â â â Hello Worldâ â â " }, "wishAsterisk": { "result": "***â â â Hello Worldâ â â ***" } }
AWS Lambda颿°ãæåŸ
ãããã©ã¡ãŒã¿ãŒã¯messageãšãããã®ããã«éäžã®åŠççµæã环ç©ããŠããããšãèããŸãã
é¢é£ããããã¥ã¡ã³ã
èŠãŠãããæ¹ããããããªããã¥ã¡ã³ãã¯ãã®ãããã§ããããã
Step Functions でワークフローの入力と出力を設定する - AWS Step Functions
Step Functions での入力と出力の処理 - AWS Step Functions
å ¥åºåãæ±ãã«ããããããã€ãã®èŠçŽ ãç»å ŽããŸãã

Step Functions での入力と出力の処理 - AWS Step Functions
ãŸããAWS Step Functionsã«ãããã¹ããŒãã®å ¥åºåã¯JSONã§æ±ããã®ã¿ããã§ãã
Step Functions ã®å®è¡ã¯å ¥åãšããŠJSONããã¹ããåãåãããã®å ¥åãã¯ãŒã¯ãããŒã®æåã®ç¶æ ã«æž¡ããŸããåã ã®ç¶æ ã¯å ¥åJSONãšããŠåä¿¡ãããéåžžã¯åºåJSONãšããŠæ¬¡ã®ç¶æ ã«æž¡ãããŸãã
InputPathã¯ãå
¥åããŒã¿ãJSON Pathã§ãã£ã«ã¿ãªã³ã°ããä»çµã¿ã§ãããã£ã«ã¿ãªã³ã°ããªãå Žåãããã©ã«ãã§$ãèšå®ããããã®ãš
ã¿ãªãããå
¥åããã®ãŸãŸã¿ã¹ã¯ã«æž¡ãããŸãã
パスを使用した Step Functions ワークフローの入力へのアクセス - AWS Step Functions
InputPathã®åŸã«å®è¡ããããã£ã«ã¿ãªã³ã°ã§ã¯ãªãããŒãšå€ãå å·¥ã§ããã®ãParametersã§ãã
ãããŸã§ãå ¥åã«é¢ãããã®ã§ãã
åºåã«é¢ãããã®ã¯ãResultSelectorãResultPathãOutputPathã®3çš®é¡ãããããã®é ã§é©çšãããŸãã
ResultSelectorã䜿ããšãåºåããŒã¿ã®ããŒãšå€ãå å·¥ã§ããŸããã¹ããŒãã®åºåããŒã¿ã§ã¯ãªããã¿ã¹ã¯ã®åºåããŒã¿ãç¯å²ãªãšããã
ãã€ã³ãã§ãã
ResultPathã¯ãã¿ã¹ã¯ã®åºåãã¹ããŒãã®åºåã®ã©ãã«å«ããããJSON Pathã§æå®ã§ããŸãããªã«ãæå®ããªããš$ãæå®ããããšã«ãªãã
ã¿ã¹ã¯ã®åºåããã®ãŸãŸã¹ããŒãã®åºåã«ãªããŸããç¹å®ã®JSON Pathãæå®ãããšããã®ãã¹ã«ã¿ã¹ã¯ã®çµæãåæ ïŒè¿œå ïŒãããŸãã
nullãæå®ãããšã¿ã¹ã¯ã®åºåã¯ç Žæ£ãããå
¥åããã®ãŸãŸã¹ããŒãã®åºåã«ãªããŸãã
ã€ãŸãããªã«ãæå®ããªããšã¹ããŒãã®åºåããŒã¿ã¯ã¿ã¹ã¯ã®åºåããŒã¿ã§çœ®ãæãããããã¹ãæå®ãããšå
¥åããŒã¿ã«å¯ŸããŠæå®ã®ãã¹ã§
ã¿ã¹ã¯ã®åºåããŒã¿ãããŒãžãããããšã«ãªããŸããã
åãã¿ãŒã³ã¯ããã¡ãã®ããŒãžãèŠãã®ããããããããšæããŸãã
Step Functions ワークフロー ResultPath で を使用して状態出力を指定する - AWS Step Functions
OutputPathã¯ãã¹ããŒãã®åºåãæå®ããJSON Pathã§ãã£ã«ã¿ãªã³ã°ãããã®ã§ãããªã«ãæå®ããªãå Žåã¯$ãæå®ãããããšã«ãªãã
ResultPathãŸã§ã®å®è¡çµæãã¹ããŒãã®åºåã«ãªããŸãã
Step Functions ワークフロー OutputPath で を使用して状態出力をフィルタリングする - AWS Step Functions
ãã®ãããã®èŠçŽ ãšãäœæããAWS Lambda颿°ã§ãé¡ã®åããããã¯ãŒã¯ãããŒãäœæããŠã¿ãããšæããŸãã
ç°å¢
ä»åã®ç°å¢ã¯ãã¡ãã
$ python3 --version Python 3.10.12 $ pip3 --version pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10) $ awslocal --version aws-cli/2.19.4 Python/3.12.6 Linux/5.15.0-125-generic exe/x86_64.ubuntu.22 $ samlocal --version SAM CLI, version 1.127.0 $ localstack --version 3.8.1
LocalStackãèµ·åã
$ localstack start
AWS Lambda颿°ãäœæãã
ããã§ã¯ãAWS Lambda颿°ãäœæããŸããAWS SAMã䜿ã£ãŠäœæãLocalStackã«ãããã€ããããšã«ããŸãã
$ samlocal init --name sfn-localstack-input-output --runtime python3.10 --app-template hello-world --package-type Zip --no-tracing --no-application-insights --structured-logging $ cd sfn-localstack-input-output
䜿ããªããã®ã¯åé€ã
$ rm -rf events hello_world tests
AWS Lambda颿°ãäœæã
æž¡ãããæååã«ãâ ããå ããAWS Lambda颿°ã
star/app.py
def lambda_handler(event, context) -> dict: print(f"star function input = {event}") message = event["message"] return { "result": ("â " * 3) + message + ("â " * 3) }
æž¡ãããæååã«ã*ããå ããAWS Lambda颿°ã
asterisk/app.py
def lambda_handler(event, context) -> dict: print(f"asterisk function input = {event}") message = event["message"] return { "result": ("*" * 3) + message + ("*" * 3), }
ã©ã¡ããå ¥åãæšæºåºåã«æžãåºãããã«ããŠããŸãã
AWS Step Functionsã®ã¹ããŒããã·ã³ã®å®çŸ©ã4ã€ã®ã¹ããŒãã§æ§æããŠããŠãAWS Lambda颿°ã®ARNã¯ãã©ã¡ãŒã¿ãŒåããŠããŸãã
statemachine/input-output-state-machine.asl.json
{ "Comment": "My Input Output State Machine", "StartAt": "WithStar", "States": { "WithStar": { "Type": "Task", "Resource": "${StarFunctionArn}", "ResultPath": "$.withStar", "Next": "FormatStarOutput" }, "FormatStarOutput": { "Type": "Pass", "Parameters": { "message.$": "$.withStar.result", "inputOriginalMessage.$": "$.message", "result.$": "$.withStar.result", "withStar.$": "$.withStar" }, "Next": "WithAsterisk" }, "WithAsterisk": { "Type": "Task", "Resource": "${AsteriskFunctionArn}", "ResultPath": "$.withAsterisk", "Next": "FormatAsteriskOutput" }, "FormatAsteriskOutput": { "Type": "Pass", "Parameters": { "result.$": "$.withAsterisk.result", "inputOriginalMessage.$": "$.inputOriginalMessage", "withStar.$": "$.withStar", "withAsterisk.$": "$.withAsterisk" }, "End": true } } }
説æã¯ãå®éã®åäœã確èªããæã«ããããšã«ããŸãã
AWS SAMãã³ãã¬ãŒãã
template.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sfn-localstack-input-output Sample SAM Template for sfn-localstack-input-output Globals: Function: Timeout: 3 LoggingConfig: LogFormat: JSON Resources: StarFunction: Type: AWS::Serverless::Function Properties: FunctionName: star-function CodeUri: star/ Handler: app.lambda_handler Runtime: python3.10 Architectures: - x86_64 AsteriskFunction: Type: AWS::Serverless::Function Properties: FunctionName: asterisk-function CodeUri: asterisk/ Handler: app.lambda_handler Runtime: python3.10 Architectures: - x86_64 InputOutputStateMachine: Type: AWS::Serverless::StateMachine Properties: Name: input-output-state-machine DefinitionUri: statemachine/input-output-state-machine.asl.json DefinitionSubstitutions: StarFunctionArn: !GetAtt StarFunction.Arn AsteriskFunctionArn: !GetAtt AsteriskFunction.Arn Outputs: StarFunction: Description: Star Lambda Function ARN Value: !GetAtt StarFunction.Arn StarFunctionIamRole: Description: Implicit IAM Role created for Star function Value: !GetAtt StarFunctionRole.Arn AsteriskFunction: Description: Asterisk Lambda Function ARN Value: !GetAtt AsteriskFunction.Arn AsteriskFunctionIamRole: Description: Implicit IAM Role created for Asterisk function Value: !GetAtt AsteriskFunctionRole.Arn InputOutputStateMachineArn: Description: "Input Output State machine ARN" Value: !Ref InputOutputStateMachine InputOutputStateMachineRoleArn: Description: "IAM Role created for Input Output State machine based on the specified SAM Policy Templates" Value: !GetAtt InputOutputStateMachineRole.Arn
ãããã€ã
$ samlocal deploy --region us-east-1
å®äºã
CloudFormation events from stack operations (refresh every 5.0 seconds) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::CloudFormation::Stack sfn-localstack-input-output - CREATE_IN_PROGRESS AWS::IAM::Role StarFunctionRole - CREATE_COMPLETE AWS::IAM::Role StarFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role AsteriskFunctionRole - CREATE_COMPLETE AWS::IAM::Role AsteriskFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role InputOutputStateMachineRole - CREATE_COMPLETE AWS::IAM::Role InputOutputStateMachineRole - CREATE_IN_PROGRESS AWS::Lambda::Function StarFunction - CREATE_COMPLETE AWS::Lambda::Function StarFunction - CREATE_IN_PROGRESS AWS::Lambda::Function AsteriskFunction - CREATE_COMPLETE AWS::Lambda::Function AsteriskFunction - CREATE_IN_PROGRESS AWS::StepFunctions::StateMachine InputOutputStateMachine - CREATE_COMPLETE AWS::StepFunctions::StateMachine InputOutputStateMachine - CREATE_COMPLETE AWS::CloudFormation::Stack sfn-localstack-input-output - --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Outputs ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Key StarFunction Description Star Lambda Function ARN Value arn:aws:lambda:us-east-1:000000000000:function:star-function Key StarFunctionIamRole Description Implicit IAM Role created for Star function Value arn:aws:iam::000000000000:role/sfn-localstack-input-output-StarFunctionRole-fc84a4ab Key AsteriskFunction Description Asterisk Lambda Function ARN Value arn:aws:lambda:us-east-1:000000000000:function:asterisk-function Key AsteriskFunctionIamRole Description Implicit IAM Role created for Asterisk function Value arn:aws:iam::000000000000:role/sfn-localstack-input-output-AsteriskFunctionRole-05ab9b1b Key InputOutputStateMachineArn Description Input Output State machine ARN Value arn:aws:states:us-east-1:000000000000:stateMachine:input-output-state-machine Key InputOutputStateMachineRoleArn Description IAM Role created for Input Output State machine based on the specified SAM Policy Templates Value arn:aws:iam::000000000000:role/sfn-localstack-input-output-InputOutputStateMachineR-33ce1d33 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sfn-localstack-input-output in us-east-1
ã§ã¯ãå®è¡ããŠã¿ãŸãã
$ awslocal stepfunctions start-execution --state-machine arn:aws:states:us-east-1:000000000000:stateMachine:input-output-state-machine --name input-output --input '{"message": "Hello World"}'
{
"executionArn": "arn:aws:states:us-east-1:000000000000:execution:input-output-state-machine:input-output",
"startDate": "2024-11-10T23:00:40.246646+09:00"
}
çµæã®ç¢ºèªã
$ awslocal stepfunctions describe-execution --execution-arn arn:aws:states:us-east-1:000000000000:execution:input-output-state-machine:input-output
{
"executionArn": "arn:aws:states:us-east-1:000000000000:execution:input-output-state-machine:input-output",
"stateMachineArn": "arn:aws:states:us-east-1:000000000000:stateMachine:input-output-state-machine",
"name": "input-output",
"status": "SUCCEEDED",
"startDate": "2024-11-10T23:00:40.246646+09:00",
"stopDate": "2024-11-10T23:00:44.402487+09:00",
"input": "{\"message\":\"Hello World\"}",
"inputDetails": {
"included": true
},
"output": "{\"result\":\"***\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605***\",\"inputOriginalMessage\":\"Hello World\",\"withStar\":{\"result\":\"\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605\"},\"withAsterisk\":{\"result\":\"***\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605***\"}}",
"outputDetails": {
"included": true
}
}
ã¡ãã£ãšãããã«ããã§ããããé¡ã§çã£ãçµæãåŸãããŠããŸãã
"output": "{\"result\":\"***\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605***\",\"inputOriginalMessage\":\"Hello World\",\"withStar\":{\"result\":\"\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605\"},\"withAsterisk\":{\"result\":\"***\\u2605\\u2605\\u2605Hello World\\u2605\\u2605\\u2605***\"}}",
ããã ãã§ã¯ãªã«ãèµ·ãã£ãã®ãã¡ãã£ãšãããã«ããã®ã§ãã¹ããŒããã·ã³ã®å®çŸ©ãšAWS Lambda颿°ã®ãã°ãçµã¿åãããªãã
èŠãŠãããŸãã
ãŸããå ¥åã¯ããã§ããã
{ "message": "Hello World" }
æåã®ã¹ããŒãã¯ããâ ãã远å ããAWS Lambda颿°ã®åŒã³åºãã§ãã
"WithStar": { "Type": "Task", "Resource": "${StarFunctionArn}", "ResultPath": "$.withStar", "Next": "FormatStarOutput" },
å ¥åããŒã¿ã®ãã°ã確èªããŠã¿ãŸãã
$ awslocal logs tail /aws/lambda/star-function
messageãæž¡ã£ãŠããŠããŸããã
2024-11-10T14:00:42.044000+00:00 2024/11/10/[$LATEST]17d5bcaada62b9edcc47ed1853b85d30 star function input = {'message': 'Hello World'}
AWS Lambda颿°ã¯å ¥åå€ã®ååŸã«ãâ ãã3ã€ã€ããã ãã§ãã
message = event["message"] return { "result": ("â " * 3) + message + ("â " * 3) }
ã€ãŸããçµæã¯ãããªããŸãã
{ "result": "â â â Hello Worldâ â â " }
ããã§ãResultPathã$.withStarã«ããŠããã®ã§
"WithStar": { "Type": "Task", "Resource": "${StarFunctionArn}", "ResultPath": "$.withStar", "Next": "FormatStarOutput" },
ã¹ããŒãã®çµæãšããŠã¯ãããªããŸãã
{ "message": "Hello World", "withStar": { "result": "â â â Hello Worldâ â â " } }
次ã®AWS Lambda颿°ã¯messageãåŠçããããã«ãªã£ãŠããã®ã§ãããå°ãå å·¥ããå¿
èŠããããŸãã
ããã§ã次ã®ã¹ããŒããAWS Lambda颿°ã®åŒã³åºãã§ã¯ãªãPassãšããããŒã¿ã®å å·¥ã«ç¹åããã¹ããŒãã«ããŸããã
"FormatStarOutput": { "Type": "Pass", "Parameters": { "message.$": "$.withStar.result", "inputOriginalMessage.$": "$.message", "result.$": "$.withStar.result", "withStar.$": "$.withStar" }, "Next": "WithAsterisk" },
Parametersã¯å
¥åããŒã¿ãå å·¥ããã®ã§ããã®çµæã¯ãããªããŸãã
{ "message": "â â â Hello Worldâ â â ", "inputOriginalMessage": "Hello World", "result": "â â â Hello Worldâ â â ", "withStar": { "result": "â â â Hello Worldâ â â " } }
ãããæ¬¡ã®ã¹ããŒãã®å ¥åããŒã¿ã«ãªããŸãã
"WithAsterisk": { "Type": "Task", "Resource": "${AsteriskFunctionArn}", "ResultPath": "$.withAsterisk", "Next": "FormatAsteriskOutput" },
ãã°ã確èªããŠã¿ãŸãããã
$ awslocal logs tail /aws/lambda/asterisk-function
FormatStarOutputã®çµæããã®ãŸãŸæž¡ãããŠããŸããã
2024-11-10T14:00:44.187000+00:00 2024/11/10/[$LATEST]9b130825c494ddffaabeb5ff65c2026c asterisk function input = {'message': 'â
â
â
Hello Worldâ
â
â
', 'inputOriginalMessage': 'Hello World', 'result': 'â
â
â
Hello Worldâ
â
â
', 'withStar': {'result': 'â
â
â
Hello Worldâ
â
â
'}}
AWS Lambda颿°ã¯ãã*ãã3ã€ã€ããããã«ãªã£ãŠããŸããã
message = event["message"] return { "result": ("*" * 3) + message + ("*" * 3), }
ãªã®ã§ãAWS Lambda颿°ã®åºåããŒã¿ãã®ãã®ã¯ä»¥äžã«ãªããŸãã
{ "result": "***â â â Hello Worldâ â â ***" }
ResultPathãã€ããŠããã®ã§ã
"WithAsterisk": { "Type": "Task", "Resource": "${AsteriskFunctionArn}", "ResultPath": "$.withAsterisk", "Next": "FormatAsteriskOutput" },
ã¹ããŒãã®åºåããŒã¿ãšããŠã¯ä»¥äžã®ããã«ãªããŸãã
{ "message": "â â â Hello Worldâ â â ", "inputOriginalMessage": "Hello World", "result": "***â â â Hello Worldâ â â ***", "withStar": { "result": "â â â Hello Worldâ â â " }, "withAsterisk": { "result": "***â â â Hello Worldâ â â ***" } }
æåŸã®ã¹ããŒãã§ã¯ãå¿
èŠãªããŒã¿ã®ã¿ãæ®ãããã«Passã¹ããŒãã§Parametersã䜿ã£ãŠå å·¥ããŸãã
"FormatAsteriskOutput": { "Type": "Pass", "Parameters": { "result.$": "$.withAsterisk.result", "inputOriginalMessage.$": "$.inputOriginalMessage", "withStar.$": "$.withStar", "withAsterisk.$": "$.withAsterisk" }, "End": true }
ã€ãŸãããããªããŸãã
{ "result": "***â â â Hello Worldâ â â ***", "inputOriginalMessage": "Hello World", "withStar": { "result": "â â â Hello Worldâ â â " }, "withAsterisk": { "result": "***â â â Hello Worldâ â â ***" } }
ãªããšãã§ããŸããããã ãã¶ãŠããããŸããâŠã
ãŠããã£ãã®ã¯ãã®ãããã§ããã
ResultSelectorã®æäœç¯å²ãã¿ã¹ã¯ã®åºåããŒã¿ã«éããŠããŠã¹ããŒãå šäœã®åºåããŒã¿ãšã¯çŽæ¥ã¯é¢ä¿ããªãããšResultPathã¯ã¹ããŒãå šäœã®åºåããŒã¿ãšã¿ã¹ã¯ã®åºåããŒã¿ã®é¢ä¿ãæžããŠããããš- ä»åã®ããã«ã¿ã¹ã¯ã®åºåããŒã¿ãã¹ããŒãã®åºåããŒã¿ã®è€æ°ã®ç®æã«åæ ããããå Žåã¯
Taskã¹ããŒãã ãã§ã¯ã ãªã§ãPassã¹ããŒãã§å å·¥ã ããè¡ãããã«ããããš
ç¹ã«ResultSelectorãåéãããŠæããŠããŠã ãã¶ããããŸããã
ãŸãããªããšããªã£ãŠããã£ãã§ãïŒç¬ïŒã
ãããã«
LocalStackãšAWS SAMã§ãAWS Lambda颿°ã䜿ã£ãå ¥åºåãæ±ãAWS Step Functionsã®ã¯ãŒã¯ãããŒãæžããŠã¿ãŸããã
æåã«é©åœã«ãé¡èšå®ããã®ã§ãããAWS Step Functionsã®ã¹ããŒãã®ããŒã¿ã®æäœæ¹æ³ãã¡ãããšçè§£ããªããŸãŸèšå®ããã®ã§ã
æã£ã以äžã«é£ãããã®ã«ãªã£ãŠããŸããŸããïŒç¬ïŒã
çµæçã«ã¯ã¹ããŒãã®ããŒã¿æäœã«é¢ããç¥èãã ãã¶åŸããããšæãã®ã§ãããšããŸãããã