AWS Lambda Durable Functionsでシステム間連携を実現するCallback機能を試してみた #AWSreInvent

AWS Lambda Durable Functionsでシステム間連携を実現するCallback機能を試してみた #AWSreInvent

2025.12.04

リテールアプリ共創部 マッハチームのるおんです。

AWS Lambda Durable Functionsには、外部システムからの入力を待ち受ける Callback機能 があります。これを使えば、「上長の承認が来るまで処理を止めておく」「外部システムからのWebhook通知を待ってから次に進む」といったワークフローを実装できます。

今回は、このCallback機能を実際に試してみました。

https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-sdk.html

Callback機能の仕組み

Callback機能を使った外部システム連携の流れは以下のようになります。

  1. Lambda関数が createCallback()コールバックID を生成
  2. コールバックIDを 外部システムに送信(Slack通知、メールなど)
  3. Lambda関数は 一時停止(待機中はコンピュート料金なし)
  4. 外部システムが Lambda APIを通じて結果を送信
  5. Lambda関数が 再開 し、結果を受け取る

今回は、シンプルに2つのLambda関数を作成して、この流れを確認してみます。

Lambda関数 役割
myDurableFunction Durable Functions。コールバックを作成して待機
callbackSuccessFunction コールバック結果を送信する関数

やってみた

1. myDurableFunction の作成

まず、コールバックを作成して外部からの応答を待機するDurable Functionを作成します。

作成手順の詳細は以下のブログを参考にしてください。

https://dev.classmethod.jp/articles/aws-lambda-durable-functions-awsreinvent/

AWS ConsoleでUS East (Ohio)リージョンにて、Durable Executionを有効にしたLambda関数を作成し、以下のコードをデプロイします。

index.mjs
import { withDurableExecution } from "@aws/durable-execution-sdk-js";

  // ダミーのモック関数
  async function sendApprovalRequest(callbackId, orderId) {
    console.log(`Approval request sent for order ${orderId}`);
    console.log(`Callback ID: ${callbackId}`);
    // 実際の実装では、Slack通知やメール送信などを行う
  }

  export const handler = withDurableExecution(async (event, context) => {
    const orderId = event.orderId;

    // 1. コールバックを作成
    const [promise, callbackId] = await context.createCallback("approval", {
      timeout: { hours: 24 },
    });

    console.log("Callback is created!");

    // 2. 外部システムに承認リクエストを送信
    await sendApprovalRequest(callbackId, orderId);

    // 3. 外部からの応答を待機
    console.log("waiting...")
    const approval = await promise;

    return {
      orderId: orderId,
      status: approval.approved ? "approved" : "rejected",
      approval: approval,
    };
  });

createCallback()を実行すると、コールバックIDPromiseのペアが返されます。このPromiseは、外部システムから該当のコールバックIDを指定して成功通知が送信されると解決されます。今回は、この後作成する別のLambda関数から成功通知を送信することで、この仕組みを検証します。

まずはテストを実行して、コールバック待機状態にしてみましょう。

2. myDurableFunction をテスト実行

以下のテストイベントで実行します。

{
  "orderId": "order-12345"
}

実行すると、await promise の部分で 待機状態 になります。

永続実行タブを確認すると、ステータスが「実行中」になっていることが確認できます。

スクリーンショット 2025-12-04 5.15.37

CloudWatch Logsには Callback ID が出力されているので、これをコピーしておきます。
また、ログに仕込んでおいた「waiting...」というログが出力されており、そこでログの出力が止まっているため待機中の状態がここからも確認できます。

スクリーンショット 2025-12-04 5.16.28

3. 成功通知を送信するLambda関数を作成

次に、結果を送信する別のLambda関数を作成します。

ローカルでの環境構築

mkdir callback-successFunction && cd callback-successFunction
pnpm init
pnpm add @aws-sdk/client-lambda@latest

コードの作成

関数の中身を記述します。この関数は、eventからcallbackIdを取得し、SendDurableExecutionCallbackSuccessCommandで成功通知を送信します。

index.mjs
import {
  LambdaClient,
  SendDurableExecutionCallbackSuccessCommand
} from "@aws-sdk/client-lambda";

const client = new LambdaClient({ region: "us-east-2" });

export const handler = async (event) => {
  const command = new SendDurableExecutionCallbackSuccessCommand({
    FunctionName: "myDurableFunction",
    CallbackId: event.callbackId,
    Result: JSON.stringify({
      approved: true,
      approver: "john@example.com"
    })
  });

  await client.send(command);
  return { statusCode: 200, body: "Callback sent" };
};

ZIP化してアップロード

zip -r function.zip index.mjs node_modules/

AWS Consoleで通常のLambda関数(Durable Executionは不要)を作成し、ZIPファイルを手動でアップロードします。

IAMポリシーの付与

callbackSuccessFunction のIAMロールに、以下のポリシーを追加します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:SendDurableExecutionCallbackSuccess",
        "lambda:SendDurableExecutionCallbackFailure"
      ],
      "Resource": "arn:aws:lambda:us-east-2:*:function:myDurableFunction"
    }
  ]
}

4. コールバックを送信して待機を解除

callbackSuccessFunction を以下のテストイベントで実行します。callbackId には、先ほどコピーしたCallback IDを設定します。

{
  "callbackId": "先ほどコピーしたCallback ID"
}

実行し、テストが成功すると、myDurableFunction の待機が解除され、処理が再開されます。
myDurableFunction の永続実行タブで確認すると、ステータスが「成功」になり、イベント履歴に「CallbackSucceeded」がapprovalとして含まれていることが確認できます。このブログを書きながら実行していたので、12分弱待機していることも見て取れますね。

スクリーンショット 2025-12-04 5.23.14

ここまでで、Callback機能を使った外部システム連携の流れを確認できました!

実際のユースケース

今回はシンプルに2つのLambda関数を作成し、手動で試しましたが、実際のユースケースではcallbackIdの連携をうまく実現する必要があります。例えば、Slackと連携した承認フローの場合は、以下のような構成になります。

1. Durable Function
   └─ createCallback() でコールバックIDを生成
   └─ Slackに通知(ボタンのvalueにcallbackIdを埋め込む)
   └─ 待機...

2. Slackでユーザーが「承認」ボタンをクリック

3. Webhook Handler(API Gateway + Lambda)
   └─ SlackからのPOSTを受け取る
   └─ callbackIdを取り出す
   └─ SendDurableExecutionCallbackSuccess を呼び出す

4. Durable Function が再開!

実際にSlackと連携した実装例は、以下のブログが参考になります。

https://dev.classmethod.jp/articles/shuntaka-durable-functions-slack-approval/

おわりに

AWS Lambda Durable FunctionsのCallback機能を使えば、外部システムからの入力を待つワークフローを簡単に実装できます。

  • 待機中はコンピュート料金が発生しない のでコスト効率が良い
  • 最大1年間 の待機が可能
  • Slack連携やメール承認フローなど、様々なユースケースに対応可能

東京リージョンで使えるようになったら、実際のプロジェクトで活用していきたいですね。

以上、どなたかの参考になれば幸いです。

参考

https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-sdk.html

https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html

https://github.com/aws/aws-durable-execution-sdk-js

この記事をシェアする

FacebookHatena blogX

関連記事