0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Lambda Durable Functions やってみた

Posted at

はじめに

AWS re:Invent 2025 で、AWS Lambda の新機能 「Lambda Durable Functions」 が発表されました。これまで AWS Lambda は 1 回の実行につき最大 15 分 という制限があり、「数十分〜数日待ってから再開する」といった処理は、Step Functions や外部データストアを組み合わせる必要がありました。Lambda Durable Functions を利用すると、ワークフローの実行状態を最大 1 年間保持でき、途中まで実行した処理を、指定したタイミングで安全に再開できます(※ 1 回あたりの Lambda 実行時間の上限は従来どおり 15 分です)。

想定されるユースケース

Lambda Durable Functions は、以下のようなケースで特に威力を発揮します。

  • ユーザー登録・申し込みから 数十分〜数日後 に通知を送信する処理
  • 無料トライアル開始後、期限前にリマインドメールを送るフロー
  • 管理者やユーザーの 承認操作を待ってから再開するワークフロー
  • 外部 API の制限を考慮した 長時間ジョブの分割実行
  • 一時的な障害発生後、途中状態から安全に再実行したい処理

従来は Step Functions や DynamoDB などを組み合わせて実装していたような処理を、
よりシンプルに構築できるようになります。

それでは、実際に Lambda Durable Functions を使ったハンズオンをやってみましょう!

ハンズオン概要

このハンズオンでは、AWS Lambda の新機能である Durable Functions(永続実行)を使用して、ユーザーの無料トライアル開始から20分後に自動的に通知を送信するワークフローを構築します。

全体アーキテクチャ

  • Amazon SNS(Standard):メール配信(Topic + Subscription)
  • AWS Lambda(Durable Functions 有効):20分待って SNS Publish

手順

ステップ 1:SNS トピック作成 & Subscription

1.1 SNS トピックの作成

  1. AWS マネジメントコンソールで SNS を開きます。
  2. 左メニュー 「トピック」「トピックの作成」 をクリックします。
  3. 以下を設定します。
    • 種別:Standard
    • 名前:DurableReminderTopic
  4. 「トピックの作成」 をクリックします。
  5. 作成後に表示される Topic ARN を控えます(あとで Lambda の環境変数に入れます)。

1.2 メール購読(Subscription)の作成

  1. 作成したトピック詳細画面で 「サブスクリプションの作成」 をクリックします。
  2. 以下を設定します。
    • プロトコル:Eメール
    • エンドポイント:通知を受け取りたいメールアドレス
  3. 「サブスクリプションの作成」 をクリックします。
  4. 入力したメールアドレス宛に届くメールの 「Confirm subscription」 をクリックし、購読を確定します。
  5. SNS コンソールへ戻り、サブスクリプションが 「確認済み」 になっていることを確認します。

ステップ 2:Lambda(Durable Functions)を作成

2.1 Lambda 関数の作成

  1. AWS マネジメントコンソールで Lambda を開きます。
  2. 「関数の作成」「一から作成」 を選びます。
  3. 以下を設定します。
    • 関数名:MyDurableSnsFunction
    • ランタイム:Node.js 24.x
    • (重要)Durable execution(永続実行)を有効化
  4. 「関数の作成」 をクリックします。

2.2 Durable 側の設定

Durable Functions は “待機してから再開する” ため、永続実行の設定が重要です。

  1. 関数画面の Durable永続設定を開きます。
  2. 以下を目安に設定します。
    • ExecutionTimeout(永続実行タイムアウト):30分

ExecutionTimeout が短いと、20分待つ前に永続実行がタイムアウトして失敗します。

2.3 環境変数の設定

  1. 「設定」「環境変数」 を開き、「編集」 をクリックします。
  2. 以下を追加します。
    • キー:SNS_TOPIC_ARN
    • 値:ステップ 1 で控えた SNS Topic ARN
  3. 保存します。

ステップ 3:IAM(権限)の設定

Durable Functions は内部でチェックポイント(状態保存/取得)を使うため、Durable用の権限が必要です。
ただし コンソールで Durable Function として作成した場合、チェックポイント関連の権限は自動で付与されます

ここでは追加で必要な SNS Publish 権限だけ最小で付与します。

3.1 実行ロールに sns:Publish を付与

  1. Lambda 関数画面 → 「設定」「アクセス権限」 を開きます。
  2. 実行ロールのリンクをクリックして IAM へ移動します。
  3. 「許可を追加」→「ポリシーをアタッチ」 を選びます。
  4. ポリシー一覧から AmazonSNSFullAccess を検索し、チェックを入れます。
  5. 「許可を追加」 をクリックしてポリシーをアタッチします。

ステップ 4:Lambda コード を用意

4.1 作業ディレクトリ作成

ローカルで以下を実行します。

mkdir durable-sns-demo
cd durable-sns-demo
npm init -y
npm install @aws/durable-execution-sdk-js @aws-sdk/client-sns

4.2 index.mjs を作成

import { withDurableExecution } from "@aws/durable-execution-sdk-js";
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

const snsClient = new SNSClient({});

export const handler = withDurableExecution(async (event, context) => {
  console.log("受信イベント:", JSON.stringify(event));

  // CLI invoke: { "userId": "xxx" }
  // Function URL等: { body: "{\"userId\":\"xxx\"}" } も想定して吸収
  const body =
    typeof event?.body === "string" ? JSON.parse(event.body) : (event ?? {});
  const userId = body?.userId;

  if (!userId) {
    return {
      statusCode: 400,
      body: JSON.stringify({ error: "userId is required" }),
    };
  }

  console.log(`[開始] userId=${userId}`);

  // 20分待機(1200秒)
  await context.wait({ seconds: 1200 });

  // 外部副作用(SNS Publish)は step に閉じ込める
  await context.step("publish-followup-mail", async () => {
    const message = `【無料トライアル】${userId}さん、開始から20分経過しました。使い方ガイドはこちら…`;
    await snsClient.send(
      new PublishCommand({
        TopicArn: process.env.SNS_TOPIC_ARN,
        Subject: "無料トライアル:オンボーディングのご案内",
        Message: message,
      })
    );
    return { ok: true };
  });

  console.log("[完了] SNS送信に成功しました。");
  return {
    statusCode: 200,
    body: JSON.stringify({ message: "Workflow completed" }),
  };
});

4.3 ZIP を作成

zip -r deploy.zip .

ステップ 5:Lambda へアップロード

  1. Lambda コンソール → 対象関数を開きます。
  2. 「コード」 タブで 「アップロード元」→「.zip ファイル」 を選択します。
  3. deploy.zip をアップロードします。
  4. 保存します。

ステップ 6:エイリアス作成

Durable Functions は エイリアスでの呼び出しが前提になります。
安全のため、エイリアス prod を作ります。

  1. Lambda 関数画面で 「エイリアス」 を開きます。
  2. 「エイリアスを作成」 をクリックします。
  3. 以下を設定します。
    • 名前:prod
    • バージョン:$LATEST
  4. 作成します。

ステップ 7:Lambda コンソールからテスト実行(Durable Functions)

Lambda コンソールの 「テスト」機能を使って、Durable Functions を 非同期で実行します。

7.1 テストイベントの設定

  1. Lambda 関数画面を開き、右上の 「テスト」 をクリックします。

  2. イベントアクション
    「保存されたイベントを編集」(または新規作成)を選択します。

  3. 以下を設定します。

    • 永続実行名(オプション)
      test
      
      ※ Durable Execution を識別するための名前です
    • 呼び出しタイプ
      非同期
      
    • イベント名
      TestEvent
      
    • イベント JSON
      {
        "userId": "ユーザー名"
      }
      
  4. 「保存」 をクリックします。

7.2 テスト実行

  1. 設定を保存後、右上の 「テスト」 をクリックします。
  2. ステータスが 成功 になることを確認します。

非同期実行のため、ここでは処理完了を待ちません。
「成功」は 受け付けられたことを意味します。

7.3 実行直後の確認(CloudWatch Logs)

テスト実行後、まず Durable Function が起動し、待機処理に入っていることを確認します。

  1. Lambda 関数画面 → 「モニタリング」 を開きます。
  2. 「CloudWatch のログを表示」 をクリックします。
  3. 最新のログストリームを開き、以下のログが出ていることを確認します。
受信イベント: {"userId":"ユーザー名"}
[開始] userId=ユーザー名

7.4 再開後の確認(Durable による再実行)

待機時間20分が経過すると、Durable Functions によって処理が再開され、
SNS 送信処理が実行されます。

CloudWatch Logs には、次のログが追加されます。

[完了] SNS送信に成功しました。

続いて、Lambda の実行レポートが出力されます。

{
  "type": "platform.report",
  "record": {
    "status": "success",
    "metrics": {
      "durationMs": 1704.706,
      "billedDurationMs": 2326
    }
  }
}

ここで重要なのは、

  • 待機時間(20分)は duration に含まれていない
  • 実際に課金されるのは、
    「起動 → 状態保存 → 再開 → SNS送信」の 実行時間のみ

という点です。

7.5 メール受信の確認

同じタイミングで、SNS から以下の内容のメールが届きます。

  • 件名:無料トライアル:オンボーディングのご案内
  • 宛先:ステップ1で購読したメールアドレス

スクリーンショット 2025-12-27 19.07.37.png

これで、

「非同期起動 → Durable による待機 → 再開 → SNS送信」

が正しく動作していることを確認できます。

クリーンアップ

ハンズオンが終わったら、不要なリソースを削除します。

SNS トピックの削除

  1. SNS → トピック → DurableReminderTopic を選択します。
  2. 「削除」 をクリックします。
  3. 確認ダイアログで指示どおり入力し、削除します。
    ※ トピックを消すとサブスクリプションも一緒に消えます。

Lambda 関数の削除

  1. Lambda → 関数一覧で MyDurableSnsFunction を選択します。
  2. 「アクション」→「削除」 を実行します。

CloudWatch Logs の削除

  1. CloudWatch → ロググループを開きます。
  2. /aws/lambda/MyDurableSnsFunction を選択します。
  3. 「アクション」→「ロググループの削除」 を実行します。

まとめ

このハンズオンでは、AWS Lambda Durable Functions を使用して、長時間待機を伴うワークフローを実装しました。

Durable Functions の主な利点は以下の通りです。

  • 待機中はコンピュート課金が発生しない
    処理の状態は永続化されますが、待機中に Lambda が実行され続けることはなく、
    課金されるのは「実際に処理が動いた時間」のみです。

  • 長時間ワークフローを Lambda 単体で実装できる
    最大 1 年間の状態保持が可能なため、
    「数十分〜数日後に再開する」処理を追加サービスなしで実現できます。

  • リプレイにより安全に再実行できる
    障害や再起動が発生しても、保存されたチェックポイントから処理を再開でき、
    ワークフロー全体の信頼性が向上します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?