背景
5つのLambda関数をStep Functionsでオーケストレーションする受注処理ワークフローをSAMで構築しました。ASL(Amazon States Language)内でLambda ARNをどう扱うかに、SAM独自の仕組みが使われていました。
1. DefinitionSubstitutionsでASL内の変数を実際のARNに置換する
OrderWorkflow:
Type: AWS::Serverless::StateMachine
Properties:
Definition:
States:
ValidateOrder:
Type: Task
Resource: "${ValidateFunctionArn}" # ← プレースホルダー
DefinitionSubstitutions:
ValidateFunctionArn: !GetAtt ValidateFunction.Arn
InventoryFunctionArn: !GetAtt InventoryFunction.Arn
PaymentFunctionArn: !GetAtt PaymentFunction.Arn
ConfirmFunctionArn: !GetAtt ConfirmFunction.Arn
ErrorHandlerFunctionArn: !GetAtt ErrorHandlerFunction.Arn
ASL定義内では"${ValidateFunctionArn}"のようなプレースホルダー文字列を書いておき、DefinitionSubstitutionsセクションで各変数を!GetAttによるリソース参照に紐付けます。デプロイ時にSAMがこれらを実際のARNに自動的に置換します。コンソール版では5つのLambda ARNをそれぞれコピー&貼り付けする必要がありましたが、SAMではARNの文字列を一度も手で扱いません。
2. LambdaInvokePolicyをLambdaごとに1行ずつ並べる
Policies:
- LambdaInvokePolicy:
FunctionName: !Ref ValidateFunction
- LambdaInvokePolicy:
FunctionName: !Ref InventoryFunction
- LambdaInvokePolicy:
FunctionName: !Ref PaymentFunction
- LambdaInvokePolicy:
FunctionName: !Ref ConfirmFunction
- LambdaInvokePolicy:
FunctionName: !Ref ErrorHandlerFunction
ステートマシンが各Lambdaを呼び出すためのlambda:InvokeFunction権限を、SAM組み込みのLambdaInvokePolicyで1関数につき1行ずつ付与しています。コンソール版では「新しいロールを作成」を選ぶだけで自動生成されるため、コンソールの方が手数は少なく見えますが、SAMではどの関数にどの権限が付与されているかがコードとして明示され、レビューやGit管理の対象になります。
3. 5つのLambdaが1つのsrc/パッケージを共有する
Globals:
Function:
Runtime: python3.12
Resources:
ValidateFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: validate.lambda_handler
InventoryFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: inventory.lambda_handler
5つの関数がすべて同じCodeUri: src/を指定し、Handlerだけがそれぞれ違うファイル・関数名を指しています。SAMはsrc/フォルダ全体を1つのZIPパッケージとしてビルド・アップロードするため、共通のユーティリティコードを複数のLambda間で共有したい場合に扱いやすい構成です。
4. ResultPathを使ったエラー情報のマージはコンソール版と共通
Catch:
- ErrorEquals: [States.ALL]
Next: HandleError
ResultPath: "$.error"
Parallelステート後にeventが配列になる仕様や、ResultPathでエラー情報を元の入力にマージする書き方は、ASLというフォーマット自体の仕様なのでコンソール版・SAM版で完全に共通です。SAMが変えているのは「ASLをどう管理・デプロイするか」の部分であり、ASL自体の記法・挙動には手を加えていません。
まとめ
DefinitionSubstitutionsによってASL内からLambda ARNの直書きを排除できる点が、複数Lambdaをオーケストレーションするワークフローをコード管理する上での最大のメリットでした。LambdaInvokePolicyを関数ごとに明示することで、権限の可視性もコンソール版より高くなります。