Skip to content

custom lmabda issue

0

import json import boto3 import cfn_response

ssm = boto3.client("ssm") secrets = boto3.client("secretsmanager")

def handler(event, context): print("Event:", json.dumps(event))

try:
    props = event["ResourceProperties"]
    secret_name = props["secretName"]
    ssm_path = props["ssmPath"]
    payload = props["payload"]

    # 1️⃣ Read password from SSM (SecureString)
    password = ssm.get_parameter(Name=ssm_path, WithDecryption=True)["Parameter"]["Value"]

    # 2️⃣ Inject password into payload
    payload["password"] = password

    # 3️⃣ Update secret value
    secrets.put_secret_value(SecretId=secret_name, SecretString=json.dumps(payload))

    # 4️⃣ Signal success to CloudFormation
    cfn_response.send(
        event,
        context,
        cfn_response.SUCCESS,
        {"Secret": secret_name},
        physicalResourceId=secret_name,
    )

except Exception as e:
    print("Error syncing secret:", str(e))
    # Signal failure to CloudFormation
    cfn_response.send(
        event,
        context,
        cfn_response.FAILED,
        {"Message": str(e)},
        physicalResourceId="SecretSyncFailed",
    )

2026-01-08T06:45:49.927+05:30 [ERROR] Runtime.ImportModuleError: Unable to import module 'index': No module named 'cfn_response' Traceback (most recent call last): 2026-01-08T06:45:49.968+05:30 INIT_REPORT Init Duration: 348.02 ms Phase: init Status: error Error Type: Runtime.ImportModuleError 2026-01-08T06:45:50.171+05:30 [WARNING] 2026-01-08T01:15:50.171Z LAMBDA_WARNING: Unhandled exception. The most likely cause is an issue in the function code. However, in rare cases, a Lambda runt

asked 9 months ago132 views

2 Answers
1

The issue occurs because the cfn_response module is not available in modern AWS Lambda Python runtimes. Lambda no longer includes this module by default, so the function fails during initialization with No module named 'cfn_response'.

This is a common problem when using Lambda-backed CloudFormation custom resources.

To fix this, you should not import cfn_response. Instead, send the response back to CloudFormation manually using the presigned ResponseURL provided in the event. This is the recommended and most reliable approach for current Lambda runtimes.

You can either embed the response logic directly in your Lambda function or package your own helper file. Embedding the logic directly is simpler and avoids deployment issues.

Once the response is sent using an HTTP PUT request, CloudFormation will correctly receive SUCCESS or FAILED and your stack will proceed without hanging.

In short, this is not a permissions or configuration issue. It is simply caused by relying on a module that is no longer shipped with Lambda, and the solution is to handle the CloudFormation response yourself.

answered 9 months ago

0

The error you're encountering is because the Lambda function is trying to import a module called 'cfn_response' which isn't available in the Lambda execution environment by default.

The 'cfn_response' module is used to send responses back to CloudFormation when implementing custom resources. To fix this issue, you have two options:

Option 1: Include the cfn_response module directly in your Lambda function code instead of importing it. You can define the module's functionality within your Lambda function.

Option 2: Create your own cfn_response.py file with the necessary functionality and include it in your Lambda deployment package.

Here's a simple implementation of the cfn_response module that you can include directly in your Lambda function:

import json
import boto3
import urllib.request

def send(event, context, response_status, response_data, physical_resource_id=None, no_echo=False):
response_body = {
'Status': response_status,
'Reason': f"See details in CloudWatch Log Stream: {context.log_stream_name}",
'PhysicalResourceId': physical_resource_id or context.log_stream_name,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
'NoEcho': no_echo,
'Data': response_data
}

response_body_json = json.dumps(response_body)
headers = {
'content-type': '',
'content-length': str(len(response_body_json))
}

try:
req = urllib.request.Request(
url=event['ResponseURL'],
data=response_body_json.encode('utf-8'),
headers=headers,
method='PUT'
)
with urllib.request.urlopen(req) as response:
print(f"Status code: {response.status}")
print(f"Status message: {response.reason}")
except Exception as e:
print(f"Error sending response: {str(e)}")

SUCCESS = "SUCCESS"
FAILED = "FAILED"

After adding this code to your Lambda function, you can remove the import statement for cfn_response and use the functions directly.
Sources
Enable Amazon GuardDuty conditionally by using AWS CloudFormation templates - AWS Prescriptive Guidance
Automate external system updates for AWS Control Tower account creation | Integration & Automation

answered 9 months ago

EXPERT

reviewed 9 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.