cfnresponse
cfnresponse is a micro Python package designed to simplify sending responses from AWS Lambda functions acting as custom resources back to AWS CloudFormation. It abstracts the HTTP call to the pre-signed S3 URL provided by CloudFormation, ensuring that stack operations (create, update, delete) complete successfully or fail gracefully. The current version is 1.1.5, and releases are infrequent, primarily for updates related to AWS Lambda runtime environments or underlying HTTP client changes.
Common errors
-
Runtime.ImportModuleError: Unable to import module 'index': No module named 'cfnresponse'
cause The cfnresponse module is not found in the Lambda execution environment. This often happens if the Lambda function code is deployed from an S3 bucket without bundling `cfnresponse`, or if the Lambda runtime doesn't automatically include it (e.g., in newer Python versions if not deployed via inline ZipFile).fixIf using a `ZipFile` property in CloudFormation, ensure your CloudFormation template explicitly sets the Lambda `Runtime` property to a supported Python version. If deploying from S3, you must package `cfnresponse` with your Lambda code or use a Lambda Layer. Verify the handler path (e.g., `index.handler`). -
/var/task/botocore/vendored/requests/api.py:67: DeprecationWarning: You are using the put() function from 'botocore.vendored.requests'.
cause This warning indicates your Lambda function is using an older version of `cfnresponse` that relied on a deprecated vendored `requests` library within `botocore`. This dependency was removed, and newer AWS Lambda runtimes no longer support it.fixUpdate your `cfnresponse` library to version 1.1.4 or newer. If deploying via `ZipFile` in CloudFormation, ensure your template's `Runtime` property is set to a recent Python version (e.g., `python3.9` or higher) to automatically pick up the latest `cfnresponse` version provided by AWS. If bundling manually, include the latest `cfnresponse`.
Warnings
- breaking The underlying HTTP client for cfnresponse changed from `botocore.vendored.requests` to `urllib3` around April 2020. AWS Lambda environments stopped supporting the vendored `requests` by December 2021. Older Lambda functions using `cfnresponse` might fail if not updated.
- gotcha Failure to call `cfnresponse.send()` for any request type (Create, Update, Delete) will cause your CloudFormation stack operation to hang and eventually time out after a long delay (typically 1 hour).
- gotcha Any Python code placed after the `cfnresponse.send()` call will not be executed. The Lambda function terminates immediately after sending the response to CloudFormation.
- gotcha Changing the `PhysicalResourceId` between an `Update` request can cause CloudFormation to treat it as a resource replacement (deletion of old, creation of new) rather than an in-place modification, leading to unexpected behavior or data loss.
Install
-
pip install cfnresponse
Imports
- send, SUCCESS, FAILED
import cfnresponse
from cfnresponse import send, SUCCESS, FAILED
Quickstart
import json
import cfnresponse
def handler(event, context):
print("Received event: " + json.dumps(event))
# Default to SUCCESS
status = cfnresponse.SUCCESS
reason = None
physical_resource_id = event.get('PhysicalResourceId', context.log_stream_name)
response_data = {}
try:
if event['RequestType'] == 'Create':
# Implement creation logic here
response_data['Message'] = 'Resource created successfully!'
# Often a unique ID for the resource is set as PhysicalResourceId
physical_resource_id = 'my-unique-resource-id'
elif event['RequestType'] == 'Update':
# Implement update logic here
response_data['Message'] = 'Resource updated successfully!'
elif event['RequestType'] == 'Delete':
# Implement deletion logic here
response_data['Message'] = 'Resource deleted successfully!'
except Exception as e:
status = cfnresponse.FAILED
reason = f'Lambda function failed: {str(e)}'
response_data['Error'] = str(e)
print(f"Error: {e}")
finally:
cfnresponse.send(event, context, status, response_data, physical_resource_id, reason=reason)
# Note: Any code after cfnresponse.send is generally not executed as the Lambda terminates.