You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CloudFormation自定义资源超时方案咨询:Lambda还是CustomResource属性?

Alright, let's tackle this question head-on—this is a super common gotcha with CloudFormation custom resources and Lambda, so it’s great you’re digging into the details!

How to Implement Timeout Handling for CloudFormation Custom Resources with Lambda

Short Answer: You Need Both Configurations

You can’t rely on just one—you have to set the timeout in the CloudFormation Custom Resource AND implement proactive timeout logic in your Lambda function. Let’s break down why and how to do each part.

1. CloudFormation Custom Resource Timeout Setting

First, define the Timeout property in your CloudFormation template’s custom resource. This tells CloudFormation how long it should wait for a response from your Lambda before marking the resource as failed.

  • The value is in minutes, with a maximum of 120 (2 hours).
  • You should set this to be slightly longer than your Lambda’s timeout (e.g., if Lambda is set to 14 minutes, set Custom Resource timeout to 15 minutes). This gives your Lambda enough buffer to detect an impending timeout and send a proper error response to CloudFormation.

Example template snippet:

MyCustomResource:
  Type: AWS::CloudFormation::CustomResource
  Properties:
    ServiceToken: !GetAtt MyCustomResourceLambda.Arn
    Timeout: 15  # Minutes, matches our Lambda's 14min timeout plus buffer

2. Proactive Timeout Logic in Lambda

The Lambda’s built-in timeout will kill the function without sending a response to CloudFormation if it hits the limit. To avoid this, you need to add logic to check how much time is left during execution, and if you’re approaching the timeout, send a deliberate failure response to CloudFormation.

Here’s a step-by-step implementation using Python (the logic translates easily to other languages):

Step 1: Get Lambda’s Timeout Value

Lambda exposes its timeout (in seconds) via the environment variable AWS_LAMBDA_FUNCTION_TIMEOUT. We’ll use this to calculate our safety threshold.

Step 2: Track Execution Time

Record the start time of your function, then periodically check how much time has passed during your long-running operations.

Step 3: Send Failure Response When Approaching Timeout

If remaining time drops below a safe threshold (e.g., 30 seconds—enough time to send the response), construct an error response and post it to CloudFormation’s callback URL.

Example Lambda code:

import time
import requests
import os

def lambda_handler(event, context):
    # Get Lambda timeout (in seconds) from environment variable
    lambda_timeout = int(os.environ['AWS_LAMBDA_FUNCTION_TIMEOUT'])
    # Set a safety threshold (30 seconds before timeout)
    timeout_threshold = lambda_timeout - 30
    start_time = time.time()

    # Your core business logic here (e.g., calling APIs, processing data)
    try:
        while True:
            # Check remaining time
            elapsed_time = time.time() - start_time
            remaining_time = lambda_timeout - elapsed_time

            if remaining_time < timeout_threshold:
                # We're approaching timeout—send failure response to CloudFormation
                send_cloudformation_response(event, context, "FAILED", "Lambda execution approaching timeout, aborting")
                return

            # Continue your work here...
            # For example: process a batch of data, call an external API, etc.
            # If your work is a single long call, wrap it with a timeout (e.g., using requests with timeout)
    except Exception as e:
        send_cloudformation_response(event, context, "FAILED", f"Error during execution: {str(e)}")
        return

    # If everything succeeds
    send_cloudformation_response(event, context, "SUCCESS", "Resource processed successfully")

def send_cloudformation_response(event, context, status, reason):
    """Send a response to CloudFormation's callback URL"""
    response_body = {
        "Status": status,
        "Reason": reason,
        "PhysicalResourceId": context.log_stream_name,
        "StackId": event["StackId"],
        "RequestId": event["RequestId"],
        "LogicalResourceId": event["LogicalResourceId"],
        "NoEcho": False
    }

    try:
        requests.post(
            event["ResponseURL"],
            json=response_body,
            headers={"Content-Type": ""},
            timeout=10
        )
    except Exception as e:
        print(f"Failed to send response to CloudFormation: {str(e)}")

Why Both Are Necessary

  • Only Custom Resource Timeout: If Lambda hits its own timeout, it dies without sending a response. CloudFormation will wait until the Custom Resource timeout expires (up to 2 hours) before marking the resource as failed—this causes unnecessary delays.
  • Only Lambda Timeout Logic: If the Custom Resource timeout is set too low, CloudFormation might mark the resource as failed before your Lambda can finish processing or send a response.

By combining both, you ensure CloudFormation doesn’t wait unnecessarily, and your Lambda always communicates its status clearly.

内容的提问来源于stack exchange,提问作者Rudzianko怒

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:57:08