Lambda durable functionsをTerraformでサクッと試してみる。

Lambda durable functionsをTerraformでサクッと試してみる。

2025.12.14

はじめに

皆様こんにちは、あかいけです。

AWS re:Invent 2025で、AWS Lambdaの新機能「Lambda durable functions」が発表されました。

Lambda durable functionsでは最大1年間の長時間実行が可能になります。
(注意:Lambdaのタイムアウト上限は15分のまま)

またチェックポイント(checkpoint)とリプレイ(replay)の仕組みを使って、ワークフローの進行状況を自動的に追跡し、中断からの回復も自動で行ってくれます。

https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html
https://aws.amazon.com/about-aws/whats-new/2025/12/lambda-durable-multi-step-applications-ai-workflows/
https://dev.classmethod.jp/articles/about-durable-functions-timeout/

そんなLambda durable functionsですが、先日Terraformも対応しました。(AWSプロバイダー v6.25.0以降)
なので今回はTerraformで作成してサクッとLambda durable functionsを試してみます。

https://github.com/hashicorp/terraform-provider-aws/releases/tag/v6.25.0

必要となるTerraformリソース

Lambda Durable Functionsを構築するために、以下のTerraformリソースを作成します。

1. aws_lambda_function

通常のLambda関数に比べて、以下の設定が追加で必要となります。

  • Durable Functions固有の設定
    • durable_config: Durable Functionsを有効化するための設定ブロック
      • execution_timeout: 最大実行時間(秒)、最大31,622,400秒(約366日)
      • retention_period: 実行状態の保持日数(1〜90日、デフォルト14日)

https://registry.terraform.io/providers/hashicorp/aws/6.25.0/docs/resources/lambda_function

2. IAM Role(実行用)

Lambda関数の実行に必要なIAMロールです。
Durable Functions特有のアクションとして、以下の権限が追加で必要です。

  • lambda:CheckpointDurableExecution: チェックポイントの作成
  • lambda:GetDurableExecutionState: 実行状態の取得

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

Terraform実装例

以下に、Lambda Durable Functionsを構築するTerraformコードの例を示します。

main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region  = "us-east-2"
}

data "archive_file" "lambda" {
  type        = "zip"
  source_dir  = "${path.module}/src"
  output_path = "${path.module}/lambda.zip"
}

#--------------------------------------------------
# IAM: Lambda Execution Role
# Lambda関数の実行に必要なロール
#--------------------------------------------------

data "aws_iam_policy_document" "lambda_assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "lambda_execution" {
  name               = "lambda-durable-functions-execution"
  assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}

resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
  role       = aws_iam_role.lambda_execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# Durable Functions用の追加権限
data "aws_iam_policy_document" "durable_execution" {
  statement {
    sid    = "DurableExecutionPermissions"
    effect = "Allow"
    actions = [
      "lambda:CheckpointDurableExecution",
      "lambda:GetDurableExecutionState"
    ]
    resources = ["${aws_lambda_function.main.arn}:*"]
  }
}

resource "aws_iam_role_policy" "durable_execution" {
  name   = "durable-execution-policy"
  role   = aws_iam_role.lambda_execution.id
  policy = data.aws_iam_policy_document.durable_execution.json
}

#--------------------------------------------------
# Lambda Function
# durable_configを指定することでDurable Functionsとして動作
#--------------------------------------------------

resource "aws_lambda_function" "main" {
  filename         = data.archive_file.lambda.output_path
  function_name    = "example-durable-function"
  role             = aws_iam_role.lambda_execution.arn
  handler          = "lambda_function.lambda_handler"
  source_code_hash = data.archive_file.lambda.output_base64sha256

  runtime     = "python3.14"
  timeout     = 30
  memory_size = 256

  # エイリアス作成のためバージョン発行が必要
  publish = true

  # このブロックを指定することでDurable Functionsとして動作する
  durable_config {
    execution_timeout = 900
    retention_period  = 7
  }

  # Durable Functionsの削除には最大60分かかる場合がある
  # https://registry.terraform.io/providers/hashicorp/aws/6.25.0/docs/resources/lambda_function#function-with-durable-configuration
  timeouts {
    delete = "60m"
  }

  depends_on = [
    aws_iam_role_policy_attachment.lambda_basic_execution,
  ]
}

#--------------------------------------------------
# Lambda Alias
# Durable Functionsは修飾されたARN(バージョン/エイリアス付き)が必要
#--------------------------------------------------

resource "aws_lambda_alias" "prod" {
  name             = "prod"
  function_name    = aws_lambda_function.main.function_name
  function_version = aws_lambda_function.main.version
}

#--------------------------------------------------
# Outputs
#--------------------------------------------------

output "function_arn" {
  description = "Lambda function ARN"
  value       = aws_lambda_function.main.arn
}

output "alias_arn" {
  description = "Lambda alias ARN (use this for invocations)"
  value       = aws_lambda_alias.prod.arn
}

サンプルLambda関数コード

以下は、公式ドキュメントに記載されているDurable Execution SDKを使用したシンプルなサンプルコードです。
注文処理のワークフローを模擬しています。

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

なおPythonのDurable FunctionsのSDKはLambdaランタイムに含まれているようで、パッケージをインストールしなくても動作しました。

src/lambda_function.py
from aws_durable_execution_sdk_python import (
    DurableContext,
    durable_execution,
    durable_step,
)
from aws_durable_execution_sdk_python.config import Duration

@durable_step
def validate_order(step_context, order_id):
    step_context.logger.info(f"Validating order {order_id}")
    return {"orderId": order_id, "status": "validated"}

@durable_step
def process_payment(step_context, order_id):
    step_context.logger.info(f"Processing payment for order {order_id}")
    return {"orderId": order_id, "status": "paid", "amount": 99.99}

@durable_step
def confirm_order(step_context, order_id):
    step_context.logger.info(f"Confirming order {order_id}")
    return {"orderId": order_id, "status": "confirmed"}

@durable_execution
def lambda_handler(event, context: DurableContext):
    order_id = event['orderId']

    # Step 1: Validate order
    validation_result = context.step(validate_order(order_id))

    # Step 2: Process payment
    payment_result = context.step(process_payment(order_id))

    # Wait for 10 seconds to simulate external confirmation
    context.wait(Duration.from_seconds(10))

    # Step 3: Confirm order
    confirmation_result = context.step(confirm_order(order_id))

    return {
        "orderId": order_id,
        "status": "completed",
        "steps": [validation_result, payment_result, confirmation_result]
    }

上記を構築後に関数を呼び出してあげると、正常にレスポンスが返ってくるかと思います。

Lambda関数の呼び出し
aws lambda invoke \
  --function-name example-durable-function:prod \
  --payload '{"orderId": "order-12345"}' \
  --region us-east-2 \
  --cli-binary-format raw-in-base64-out \
  response.json
response.json (実行結果)
{
    "orderId": "order-12345",
    "status": "completed",
    "steps": [
        {
            "orderId": "order-12345",
            "status": "validated"
        },
        {
            "orderId": "order-12345",
            "status": "paid",
            "amount": 99.99
        },
        {
            "orderId": "order-12345",
            "status": "confirmed"
        }
    ]
}

またマネジメントコンソールからも正常に実行完了していることが確認できます。

スクリーンショット 2025-12-14 23.13.33

構築時の注意点

ドキュメントを眺めていて、いくつか注意点があったので記載します。
構築時はこれらの点を考慮した上で、検証してみて下さい。

リージョン制限

Lambda Durable Functionsは現在、US East (Ohio) / us-east-2リージョンのみで利用可能です。

なおドキュメント上だとUS East (Ohio)のみとなっっていますが、ブログ執筆時点(2025/12/14)にてus-east-1でも作成できました。
とはいえ、現状では東京リージョン(ap-northeast-1)で利用できないので注意してください。

https://aws.amazon.com/about-aws/whats-new/2025/12/lambda-durable-multi-step-applications-ai-workflows/

サポートされるランタイム

Lambda Durable Functionsでは、以下のランタイムのみサポートされています。

  • Node.js 22、24
  • Python 3.13、3.14

https://aws.amazon.com/about-aws/whats-new/2025/12/lambda-durable-multi-step-applications-ai-workflows/

修飾されたARNが必要

Durable Functionsの呼び出しには、バージョン番号またはエイリアスを含む修飾されたARNが必要です。
また$LATESTでも動作しますが、本番環境ではバージョンまたはエイリアスの使用が推奨されています。

# OK: エイリアス付き
aws lambda invoke --function-name example-durable-function:prod ...

# OK: バージョン番号付き
aws lambda invoke --function-name example-durable-function:1 ...

# 開発時のみ: $LATEST
aws lambda invoke --function-name example-durable-function:$LATEST ...

https://docs.aws.amazon.com/lambda/latest/dg/durable-invoking.html#durable-invoking-qualified-arns

決定論的なコードが必要

Durable Functionsはリプレイ(replay)の仕組みを使用するため、コードは決定論的(deterministic)である必要があります。
そのため以下のような非決定論的な操作はstep内にラップする必要があります。

  • 乱数生成とUUID生成
  • 現在の時刻またはタイムスタンプの取得
  • 外部API呼び出しとデータベースクエリ
  • ファイルシステム操作

https://docs.aws.amazon.com/lambda/latest/dg/durable-best-practices.html#durable-determinism

実行状態の保持期間

Terraformの設定では、aws_lambda_functionretention_periodで指定した日数だけ、実行状態が保持されます。

この期間を過ぎると実行履歴やチェックポイントが削除されるため、監査要件に応じて適切な値を設定してください。

さいごに

以上、Lambda Durable FunctionsをTerraformで実装する方法でした。

Lambda Durable Functionsは、従来Step Functionsでしか実現できなかった長時間ワークフローを、使い慣れたプログラミング言語で実装できる点が大きな魅力です。
コードファーストなアプローチを好む開発者や、既存のLambdaコードを拡張したいケースでは、有力な選択肢になりそうです。

おそらく今後も様々な利用用途が開拓されていく気がするので、将来的に東京リージョンに対応することに期待したいですね。
この記事が誰かのお役に立てば幸いです。

この記事をシェアする

FacebookHatena blogX

関連記事