Amazon Web Services 한국 블로그
AWS Lambda durable functions 출시 – 다단계 애플리케이션과 AI 워크플로우 구축 가능
최신 애플리케이션은 다단계 결제 처리, AI 에이전트 오케스트레이션, 사람의 결정을 기다리는 승인 프로세스 등 서비스 간의 복잡하고 장기적인 조정을 점점 더 요구합니다. 기존에는 이러한 기능을 구축하는 데 상태 관리, 장애 처리, 여러 인프라 서비스 통합 등 상당한 노력이 필요했습니다.
오늘부터 AWS Lambda durable functions를 사용하여 익숙한 AWS Lambda 환경에서 직접 안정적인 다단계 애플리케이션을 구축할 수 있습니다. Durable functions는 기존에 익숙했던 것과 동일한 이벤트 핸들러 및 통합 기능을 갖춘 일반적인 Lambda 함수입니다. 선호하는 프로그래밍 언어로 순차적 코드를 작성하면, Durable functions가 진행 상황을 추적하고, 실패 시 자동으로 재시도하며, 대기 시간 동안 유휴 컴퓨팅 비용을 지불하지 않고 지정된 시점부터 최대 1년 동안 실행을 일시 중단합니다.
AWS Lambda durable functions는 지속형 실행이라고 하는 체크포인트 및 재생 메커니즘을 사용하여 이러한 기능을 제공합니다. 지속형 실행을 위한 함수를 활성화한 후, 새로운 오픈 소스 지속형 실행 SDK를 함수 코드에 추가합니다. 그런 다음 ‘단계’와 같은 SDK 기본 요소를 사용하여 비즈니스 로직에 자동 체크포인트 및 재시도를 추가하고, ‘대기’를 사용하여 컴퓨팅 비용 없이 실행을 효율적으로 일시 중단합니다. 실행이 예기치 않게 종료되면 Lambda는 마지막 체크포인트부터 다시 시작하여 완료된 작업은 건너뛰고 이벤트 핸들러를 처음부터 재생합니다.
AWS Lambda durable functions 시작하기
Durable functions를 사용하는 방법을 안내해 드리겠습니다.
먼저 콘솔에서 새로운 Lambda 함수를 생성하고 새로 작성을 선택합니다. 지속적인 실행 섹션에서 활성화를 선택합니다. Durable functions 설정은 함수 생성 중에만 설정할 수 있으며, 현재 기존 Lambda 함수에서는 수정할 수 없습니다.

Lambda durable functions를 생성한 후 제공된 코드로 작업을 시작할 수 있습니다.

Lambda durable functions는 상태 관리 및 복구를 처리하는 두 가지 핵심 기본 요소를 도입합니다.
- 단계 –
context.step()메서드는 비즈니스 로직에 자동 재시도 및 체크포인트를 추가합니다. 단계가 완료되면 재생 중에는 해당 단계를 건너뛰게 됩니다. - 대기 –
context.wait()메서드는 지정된 기간 동안 실행을 일시 중지하여 함수를 종료하고, 컴퓨팅 비용 없이 실행을 일시 중지했다가 다시 시작합니다.
또한 Lambda durable functions는 더 복잡한 패턴을 위한 다른 연산을 제공합니다. create_callback()은 API 응답이나 사용자 승인과 같은 외부 이벤트에 대한 결과를 기다리는 데 사용할 수 있는 콜백을 생성하고, wait_for_condition()은 프로세스 완료를 위해 REST API를 폴링하는 등의 특정 조건이 충족될 때까지 일시 중지하며, parallel() 또는 map() 연산은 고급 동시성 사용 사례를 위한 연산입니다.
프로덕션 환경에 바로 적용 가능한 주문 처리 워크플로 구축
이제 기본 예를 확장하여 프로덕션 환경에 바로 적용 가능한 주문 처리 워크플로를 구축해 보겠습니다. 이 예에서는 외부 승인에 콜백을 사용하고, 오류를 적절하게 처리하고, 재시도 전략을 구성하는 방법을 보여줍니다. 이러한 핵심 개념에 집중하기 위해 코드를 의도적으로 간결하게 유지했습니다. 전체 구현에서는 Amazon Bedrock을 사용하여 검증 단계를 개선하여 AI 기반 주문 분석을 추가할 수 있습니다.
주문 처리 워크플로의 작동 방식은 다음과 같습니다.
- 먼저
validate_order()는 주문 데이터를 확인하여 모든 필수 필드가 있는지 확인합니다. - 다음으로,
send_for_approval()은 외부 사람의 승인을 위해 주문을 전송하고 콜백 응답을 기다리며, 컴퓨팅 비용 없이 실행을 일시 중단합니다. - 그런 다음
process_order()는 주문 처리를 완료합니다. - 워크플로 전체에서 try-catch 오류 처리는 실행을 즉시 중단하는 최종 오류와 자동 재시도를 트리거하는 단계 내부의 복구 가능한 오류를 구분합니다.
다음은 단계 정의와 기본 핸들러를 포함한 전체 주문 처리 워크플로입니다.
import random
from aws_durable_execution_sdk_python import (
DurableContext,
StepContext,
durable_execution,
durable_step,
)
from aws_durable_execution_sdk_python.config import (
Duration,
StepConfig,
CallbackConfig,
)
from aws_durable_execution_sdk_python.retries import (
RetryStrategyConfig,
create_retry_strategy,
)
@durable_step
def validate_order(step_context: StepContext, order_id: str) -> dict:
"""Validates order data using AI."""
step_context.logger.info(f"Validating order: {order_id}")
# In production: calls Amazon Bedrock to validate order completeness and accuracy
return {"order_id": order_id, "status": "validated"}
@durable_step
def send_for_approval(step_context: StepContext, callback_id: str, order_id: str) -> dict:
"""Sends order for approval using the provided callback token."""
step_context.logger.info(f"Sending order {order_id} for approval with callback_id: {callback_id}")
# In production: send callback_id to external approval system
# The external system will call Lambda SendDurableExecutionCallbackSuccess or
# SendDurableExecutionCallbackFailure APIs with this callback_id when approval is complete
return {
"order_id": order_id,
"callback_id": callback_id,
"status": "sent_for_approval"
}
@durable_step
def process_order(step_context: StepContext, order_id: str) -> dict:
"""Processes the order with retry logic for transient failures."""
step_context.logger.info(f"Processing order: {order_id}")
# Simulate flaky API that sometimes fails
if random.random() > 0.4:
step_context.logger.info("Processing failed, will retry")
raise Exception("Processing failed")
return {
"order_id": order_id,
"status": "processed",
"timestamp": "2025-11-27T10:00:00Z",
}
@durable_execution
def lambda_handler(event: dict, context: DurableContext) -> dict:
try:
order_id = event.get("order_id")
# Step 1: Validate the order
validated = context.step(validate_order(order_id))
if validated["status"] != "validated":
raise Exception("Validation failed") # Terminal error - stops execution
context.logger.info(f"Order validated: {validated}")
# Step 2: Create callback
callback = context.create_callback(
name="awaiting-approval",
config=CallbackConfig(timeout=Duration.from_minutes(3))
)
context.logger.info(f"Created callback with id: {callback.callback_id}")
# Step 3: Send for approval with the callback_id
approval_request = context.step(send_for_approval(callback.callback_id, order_id))
context.logger.info(f"Approval request sent: {approval_request}")
# Step 4: Wait for the callback result
# This blocks until external system calls SendDurableExecutionCallbackSuccess or SendDurableExecutionCallbackFailure
approval_result = callback.result()
context.logger.info(f"Approval received: {approval_result}")
# Step 5: Process the order with custom retry strategy
retry_config = RetryStrategyConfig(max_attempts=3, backoff_rate=2.0)
processed = context.step(
process_order(order_id),
config=StepConfig(retry_strategy=create_retry_strategy(retry_config)),
)
if processed["status"] != "processed":
raise Exception("Processing failed") # Terminal error
context.logger.info(f"Order successfully processed: {processed}")
return processed
except Exception as error:
context.logger.error(f"Error processing order: {error}")
raise error # Re-raise to fail the execution
이 코드는 몇 가지 중요한 개념을 보여줍니다.
- 오류 처리 – try-catch 블록은 터미널 오류를 처리합니다. 처리되지 않은 예외가 단계 외부에서 발생하면(예: 유효성 검사) 실행이 즉시 종료됩니다. 이 코드는 잘못된 주문 데이터와 같이 재시도할 필요가 없을 때 유용합니다.
- 단계 재시도 –
process_order단계 내에서 예외는 기본값(1단계) 또는 구성된RetryStrategy(5단계)에 따라 자동 재시도를 트리거합니다. 이 코드는 일시적인 API 사용 불가능과 같은 일시적인 오류를 처리합니다. - 로깅 – 기본 핸들러에는
context.logger를 사용하고 단계 내에서는step_context.logger를 사용합니다. 컨텍스트 로거는 재생 중에 중복 로그를 억제합니다.
이제 order_id로 테스트 이벤트를 생성하고 함수를 비동기적으로 간접 호출하여 주문 워크플로를 시작합니다. 테스트 탭으로 이동하여 이 실행을 식별하기 위해 선택 사항인 지속적인 실행 이름을 입력합니다. Durable functions는 기본적으로 멱등성을 제공합니다. 동일한 실행 이름으로 함수를 두 번 간접 호출하면 두 번째 간접 호출에서는 중복을 생성하는 대신 기존 실행 결과가 반환됩니다.

Lambda 콘솔의 지속적인 실행 탭으로 이동하여 실행을 모니터링할 수 있습니다.

여기에서 각 단계의 상태와 타이밍을 확인할 수 있습니다. 실행 시 CallbackStarted 다음에 InvocationCompleted가 표시되는데, 이는 함수가 종료되었고 승인 콜백을 기다리는 동안 유휴 요금 부과를 방지하기 위해 실행이 일시 중단되었음을 나타냅니다.

이제 전송 성공 또는 전송 실패를 선택하거나 Lambda API를 사용하여 프로그래밍 방식으로 콘솔에서 직접 콜백을 완료할 수 있습니다.

전송 성공을 선택합니다.

콜백이 완료되면 실행이 재개되어 주문을 처리합니다. 시뮬레이션된 불안정한 API로 인해 process_order 단계가 실패하는 경우, 구성된 전략에 따라 자동으로 재시도합니다. 모든 재시도가 성공하면 실행이 성공적으로 완료됩니다.

Amazon EventBridge를 사용한 실행 모니터링
Amazon EventBridge를 사용하여 실행형 함수 실행을 모니터링할 수도 있습니다. Lambda는 실행 상태 변경 이벤트를 기본 이벤트 버스로 자동 전송하므로 다운스트림 워크플로를 구축하거나, 알림을 전송하거나, 다른 AWS 서비스와 통합할 수 있습니다.
이러한 이벤트를 수신하려면 다음 패턴을 사용하여 기본 이벤트 버스에 EventBridge 규칙을 생성하세요.
{
"source": ["aws.lambda"],
"detail-type": ["Durable Execution Status Change"]
}
알아야 할 사항
주요 사항은 다음과 같습니다.
- 가용성 – Lambda durable functions는 이제 미국 동부(오하이오) AWS 리전에서 사용할 수 있습니다. 최신 리전별 이용 가능 여부는 리전별 AWS 기능 페이지를 참조하세요.
- 프로그래밍 언어 지원 – AWS Lambda durable functions는 출시 시점에 JavaScript/TypeScript(Node.js 22/24) 및 Python(3.13/3.14)을 지원합니다. 선호하는 패키지 관리자를 사용하여 함수 코드와 지속형 실행 SDK를 번들링하는 것이 좋습니다. SDK는 빠르게 변하므로 새로운 기능이 출시될 때마다 종속성을 쉽게 업데이트할 수 있습니다.
- Lambda 버전 사용 – 프로덕션 환경에 Durable functions를 배포할 때 Lambda 버전을 사용하여 재생이 항상 동일한 코드 버전에서 실행되도록 합니다. 실행이 일시 중단된 상태에서 함수 코드를 업데이트하면 재생은 실행을 시작한 버전을 사용하므로 장시간 실행되는 워크플로에서 코드 변경으로 인한 불일치를 방지할 수 있습니다.
- Durable functions 테스트 – pytest 통합 기능을 갖춘 별도의 테스트 SDK와 더욱 복잡한 통합 테스트를 위한 AWS Serverless Application Model(AWS SAM) 명령줄 인터페이스(CLI)를 사용하여 AWS 자격 증명 없이 로컬에서 Durable functions를 테스트할 수 있습니다.
- 오픈 소스 SDK – 지속형 실행 SDK는 JavaScript/TypeScript 및 Python용 오픈 소스입니다. 소스 코드를 검토하고, 개선 사항에 기여하고, 최신 기능에 대한 최신 정보를 얻을 수 있습니다.
- 요금 – AWS Lambda durable functions 요금에 대해 자세히 알아보려면 AWS Lambda 요금 페이지를 참조하세요.
AWS Lambda 콘솔을 방문하여 AWS Lambda durable functions를 시작하세요. 자세히 알아보려면 AWS Lambda durable functions 설명서 페이지를 참조하세요.
즐겁게 빌드해 보세요!
– Donnie