のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

AWS Step Functions から AWS Lambda 関数を呼び出す方法を整理してみた

前回記事に引き続き、AWS Step Functions がテーマです。

(2024 年 6 月に検証した内容に基づいています。)

AWS Step Functions のステートマシンは、様々な AWS サービスと連携できます。

例えば、AWS Lambda 関数を呼び出したり、Amazon SNS のトピックにメッセージを発行したり、Amazon DynamoDB のテーブルに項目を Put することも可能です。

この連携のことを 「統合 (integration)」と呼ぶこともあります。

この統合には、最適化された統合AWS SDK サービス統合 の 2 種類があるとドキュメントにも記載されており、それぞれの違いやサポートしているサービスなどが記載されています。

docs.aws.amazon.com

ただし、ステートマシンから AWS Lambda 関数を呼び出す方法を考えた場合、最適化された統合AWS SDK サービス統合 だけでなく、もう一つの方法があります。

この方法については AWS Step Functions の開発者ガイド で詳細に説明されているわけではありませんが、Amazon ステートメント言語の仕様や古い AWS Step Functions の公開情報には例として掲載されています。

この方法は特に名前がないのですが、この記事では便宜上、"レガシー" と呼ぶことにします。

つまり、ステートマシンから AWS Lambda 関数を呼び出す場合は、最適化された統合AWS SDK サービス統合レガシー の 3 種類の方法があるということになります。

具体的な例を見ていきましょう。

次のステートマシンの Amazon ステートメント言語 (ASL) の例では、この3種類の方法を試しています。

{
  "StartAt": "Lambda invoke Legacy",
  "States": {
    "Lambda invoke Legacy": {
      "Next": "Lambda invoke Optimized",
      "Type": "Task",
      "Comment": "Get Circuit Status",
      "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:Hello:$LATEST",
      "Parameters": {
        "greeting": "Legacy"
      }
    },
    "Lambda invoke Optimized": {
      "Type": "Task",
      "Next": "Lambda Invoke SDK",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:Hello:$LATEST",
        "Payload": {
          "greeting": "Optimized"
        }
      },
      "OutputPath": "$.Payload"
    },
    "Lambda Invoke SDK": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:lambda:invoke",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:Hello",
        "Payload": {
          "greeting": "SDK"
        }
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException",
            "Lambda.TooManyRequestsException"
          ],
          "IntervalSeconds": 1,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "End": true,
      "OutputPath": "$.Payload"
    }
  }
}

このステートマシンでは、最適化された統合AWS SDK サービス統合レガシー の異なる方法で同じ AWS Lambda 関数を呼び出していますが、 ASL を見ると、定義内容が異なっていることがわかります。

例えば Resource の指定は方法毎に異なります。

方法 Resource の内容
レガシー arn:aws:lambda:ap-northeast-1:123456789012:function:Hello:$LATEST
最適化された統合 arn:aws:states:::lambda:invoke
AWS SDK サービス統合 arn:aws:states:::aws-sdk:lambda:invoke

また、Parameters の指定は、レガシー だけが異なります。

  • レガシーの場合
"Parameters": {
        "greeting": "Legacy"
      }
  • レガシー以外の場合
"Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:Hello:$LATEST",
        "Payload": {
          "greeting": ...
        }
      }

さらに、このステートマシンを実行したときに Lambda関数がリターンした値は、AWS SDK サービス統合 だけが異なります。 これについては、ドキュメントにも記載があり、AWS SDK サービス統合 の場合、レスポンスの Payload フィールドは、JSONエスケープした文字列 から JSON への解析・変換が行われません。 docs.aws.amazon.com

  • AWS SDK サービス統合の場合

  • AWS SDK サービス統合以外の場合


では、AWS マネジメントコンソールでステートマシンを作成する場合、これら 3 つの方法を指定できるでしょうか?

AWS マネジメントコンソールから GUI でステートマシンを作成する場合、[アクション] のコンポーネントで ”AWS Lambda invoke” をドラッグ & ドロップしてステートマシンを作成する限りは、最適化された統合 または AWS SDK サービス統合 になるので、レガシー になることはありません。

ただ、コードのエディタで レガシー を使った ASL を記述することは可能です。それを AWS マネジメントコンソール で GUI デザインのモードで表示すると、一見 最適化された統合AWS SDK サービス統合 と同じように表示されます。

しかしながら、右側に表示されるプロパティの設定エリアでは、最適化された統合AWS SDK サービス統合レガシー でそれぞれ異なります。

下図は レガシー のプロパティを表示した時のものです。ベーシック というリンクがあり、それをクリックすると吹き出しで補足説明が表示されます。

また上図の吹き出しの説明文を読む限り、最適化された統合 または AWS SDK サービス統合 が推奨のように読み取れますね。

ただし、世の中で公開されているステートマシンのサンプルには レガシー が使われているものもありますので、このような方法がある、ということは留意しておいた方が良さそうです。


このように、ステートマシンから AWS Lambda 関数を呼び出す方法については、これまでは何となくは理解していたのですが詳細までは把握できていませんでした。

しかし、今回改めて確認し、記事にまとめることで自分の中で整理できたのでよかったと思ってます。

どなたかの参考になれば嬉しいです!


/* -----codeの行番号----- */