AWS Step Functions でワークフローを構築しているときに AWS Step Functions の実行時に渡すインプットの一部をファイルとして Amazon S3 に保存したいという場面があったりする❗️実際に最近あった \( 'ω')/
もちろん AWS Lambda 関数を追加すれば柔軟で自由度高くワークフローを拡張できるけど,比較的シンプルな処理であれば無理に AWS Lambda 関数を増やすのではなく,AWS Step Functions の「AWS SDK 統合」を活用する方が良かったりする.ちなみにシンプルな処理であれば AWS Lambda 関数は不要というベストプラクティスは「直接統合 (Direct Integrations)」という表現で AWS Well-Architected Framework Serverless Applications Lens に載っている👌
ワークフロー
今回は動作確認のために AWS SDK 統合 s3:PutObject
のみを設定する.
そして,アップロードする Amazon S3 バケットのオブジェクトキーは AWS Step Functions の実行名とインプットとして渡す name
を組み合わせるため,AWS Step Functions の組み込み関数 States.Format
と AWS Step Functions のコンテキストオブジェクト $$.Execution.Name
を設定する.
今回は AWS CDK でワークフローを実装した.
import { Stack, StackProps, aws_s3, aws_stepfunctions, aws_stepfunctions_tasks, } from 'aws-cdk-lib' import { Construct } from 'constructs' export class SandboxCdkStepfunctionsPutObjectStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props) const bucket = new aws_s3.Bucket(this, 'Bucket', { bucketName: 'kakakakakku-sandbox-stepfunctions-put-object', }) const putObjectTask = new aws_stepfunctions_tasks.CallAwsService(this, 'PutObjectTask', { service: 's3', action: 'putObject', parameters: { 'Bucket': bucket.bucketName, 'Key.$': `States.Format('{}/{}', $$.Execution.Name, $.name)`, 'Body.$': '$.body', 'ContentType': 'application/json', }, iamResources: ['*'], }) new aws_stepfunctions.StateMachine(this, 'SandboxCdkStepfunctions', { stateMachineName: 'sandbox-cdk-stepfunctions-put-object', definitionBody: aws_stepfunctions.DefinitionBody.fromChainable(putObjectTask), }) } }
最終的にデプロイされたワークフロー定義は以下👌
{ "StartAt": "PutObjectTask", "States": { "PutObjectTask": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:s3:putObject", "Parameters": { "Bucket": "kakakakakku-sandbox-stepfunctions-put-object", "Key.$": "States.Format('{}/{}', $$.Execution.Name, $.name)", "Body.$": "$.body", "ContentType": "application/json" } } } }
動作確認
2種類のインプットを準備して,ワークフローを実行する❗️
{ "name": "sandbox001.json", "body": { "title": "title001", "body": "body001" } }
{ "name": "sandbox002.json", "body": { "title": "title002", "body": "body002" } }
すると,期待通りに Amazon S3 バケットにオブジェクトが追加されている👌
$ aws s3api list-objects --bucket kakakakakku-sandbox-stepfunctions-put-object | jq -r '.Contents[].Key' f32ea288-3103-4c8a-9b65-6c57298420f8/sandbox002.json f5f16907-279b-447a-9e1c-eddc44ea78e3/sandbox001.json
そして f5f16907-279b-447a-9e1c-eddc44ea78e3/sandbox001.json
を開くと,期待通りにインプットの body
に指定した JSON になっていた👌
{"title":"title001","body":"body001"}