{"id":9531,"library":"aws-cdk-custom-resources","title":"AWS CDK Custom Resources (v1)","description":"The `aws-cdk-custom-resources` library, currently at version `1.204.0`, provides constructs within the AWS Cloud Development Kit (CDK) for implementing custom resources in CloudFormation. These resources extend CloudFormation capabilities by integrating with other AWS services or even third-party APIs. This package is part of the CDK v1 ecosystem, which is now in maintenance mode, receiving only critical updates. Users are encouraged to migrate to AWS CDK v2 for new development.","status":"maintenance","version":"1.204.0","language":"en","source_language":"en","source_url":"https://github.com/aws/aws-cdk.git","tags":["aws","cdk","custom-resources","cloudformation","infrastructure-as-code","cloud"],"install":[{"cmd":"pip install aws-cdk-custom-resources","lang":"bash","label":"Install AWS CDK Custom Resources v1"}],"dependencies":[{"reason":"Core CDK constructs and app lifecycle, required for all CDK applications.","package":"aws-cdk.core","optional":false},{"reason":"Runtime for JSII-generated Python modules.","package":"jsii","optional":false}],"imports":[{"note":"Common misspelling of the module path.","wrong":"from aws_cdk.aws_custom_resources import AwsCustomResource","symbol":"AwsCustomResource","correct":"from aws_cdk.custom_resources import AwsCustomResource"},{"symbol":"AwsCustomResourcePolicy","correct":"from aws_cdk.custom_resources import AwsCustomResourcePolicy"},{"symbol":"PhysicalResourceId","correct":"from aws_cdk.custom_resources import PhysicalResourceId"},{"note":"Used for Lambda-backed custom resources where you provide the provider function.","symbol":"CustomResource","correct":"from aws_cdk.custom_resources import CustomResource"}],"quickstart":{"code":"import os\nfrom aws_cdk import (\n    Stack,\n    App,\n    Duration,\n)\nfrom aws_cdk.aws_s3 import Bucket\nfrom aws_cdk.custom_resources import (\n    AwsCustomResource,\n    AwsCustomResourcePolicy,\n    PhysicalResourceId,\n)\nfrom constructs import Construct\n\nclass MyCustomResourceStack(Stack):\n    def __init__(self, scope: Construct, id: str, **kwargs) -> None:\n        super().__init__(scope, id, **kwargs)\n\n        # Create an S3 bucket to interact with\n        bucket = Bucket(self, \"MyCustomResourceBucket\")\n\n        # Use AwsCustomResource to call S3 listObjectsV2 API\n        # This construct makes direct SDK calls from CloudFormation\n        s3_list_caller = AwsCustomResource(\n            self,\n            \"S3ListCaller\",\n            on_create={\n                \"service\": \"S3\",\n                \"action\": \"listObjectsV2\",\n                \"parameters\": {\n                    \"Bucket\": bucket.bucket_name,\n                },\n                \"physical_resource_id\": PhysicalResourceId.of(f\"my-s3-lister-{bucket.bucket_name}\"),\n            },\n            on_update={\n                \"service\": \"S3\",\n                \"action\": \"listObjectsV2\",\n                \"parameters\": {\n                    \"Bucket\": bucket.bucket_name,\n                },\n                \"physical_resource_id\": PhysicalResourceId.of(f\"my-s3-lister-{bucket.bucket_name}\"),\n            },\n            # on_delete is optional; here it's not needed for a read-only action\n            # For resources that create external entities, on_delete is critical for cleanup.\n            policy=AwsCustomResourcePolicy.from_sdk_calls(\n                resources=[bucket.bucket_arn, bucket.bucket_arn + \"/*\"]\n            ),\n            timeout=Duration.minutes(2)\n        )\n\n        # You can retrieve outputs from the SDK call result\n        # For listObjectsV2, it returns a list of contents. Here, we just get the Request ID.\n        request_id = s3_list_caller.get_response_field(\"ResponseMetadata.RequestId\")\n        # In a real application, you might use this output, e.g., CfnOutput(self, \"RequestId\", value=request_id)\n\napp = App()\nMyCustomResourceStack(app, \"MyCustomResourceExampleStack\")\napp.synth()","lang":"python","description":"This quickstart demonstrates how to use `AwsCustomResource` to make a direct AWS SDK call (listing objects in an S3 bucket) from a CDK stack. This construct simplifies interaction with AWS APIs that don't have direct CloudFormation support. Remember that `aws-cdk-custom-resources` is a V1 package."},"warnings":[{"fix":"For new projects, prefer installing `aws-cdk` (the monolithic v2 package) and utilize its bundled `custom_resources` module directly. For existing V1 projects, ensure all `aws-cdk.*` packages are consistently pinned to compatible V1 versions (e.g., all `1.x.y`).","message":"This package is part of AWS CDK v1, which is in maintenance mode and no longer receives new features. While the `aws_cdk.custom_resources` module exists in CDK v2, using this V1 package (`aws-cdk-custom-resources`) alongside a CDK v2 project can lead to dependency conflicts and unexpected behavior due to different core libraries and versioning strategies.","severity":"breaking","affected_versions":"All versions of `aws-cdk-custom-resources` (as it's a V1 package)."},{"fix":"Always attach `AwsCustomResourcePolicy.from_sdk_calls()` or a specific `iam.PolicyStatement` to the custom resource's execution role. This policy must grant the *exact* permissions needed for the SDK calls being made. Check CloudWatch logs (usually under `/aws/lambda/`) for precise `AccessDeniedException` messages.","message":"Custom Resources, especially `AwsCustomResource`, require careful IAM permissions. If the underlying SDK call fails due to insufficient permissions, CloudFormation deployment will often fail with a generic 'Custom Resource failed' message, and details are only found in CloudWatch logs.","severity":"gotcha","affected_versions":"All."},{"fix":"Design `on_create`, `on_update`, and `on_delete` handlers to be idempotent. Always use `PhysicalResourceId.of('a-stable-unique-id')` that uniquely identifies the *managed external resource* (not the custom resource itself) and remains constant across deployments for the same logical resource.","message":"Ensuring a stable and unique `PhysicalResourceId` is crucial for custom resources, particularly for `on_update` and `on_delete` operations. A changing `PhysicalResourceId` or one that is not unique across deployments can lead to resource abandonment, orphaned resources, or unintended side effects during updates or rollbacks.","severity":"gotcha","affected_versions":"All."},{"fix":"Ensure your Lambda provider function returns a valid CloudFormation custom resource response object. For Python, the `cfnresponse` library is commonly used. Monitor Lambda logs for errors and ensure the function completes within the `timeout` specified for the Custom Resource.","message":"Lambda-backed custom resources (using `CustomResource` with a `provider`) must return a specific JSON response format to CloudFormation within the specified timeout. Incorrect formats or exceeding the timeout will cause the CloudFormation deployment to fail.","severity":"gotcha","affected_versions":"All."}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Navigate to the specified CloudWatch log group in the AWS console. Examine the logs for specific error messages (e.g., `AccessDeniedException`, Python tracebacks) and adjust IAM policies or fix the custom resource's handler code accordingly.","cause":"This generic error typically indicates an issue within the custom resource's execution, most commonly insufficient IAM permissions for the underlying SDK calls or an error in the custom resource's handler code.","error":"CloudFormation Custom Resource failed. See details in CloudWatch log group /aws/lambda/..."},{"fix":"Ensure `pip install aws-cdk-custom-resources` has been successfully run within your virtual environment. Verify that the correct virtual environment is active. If migrating to V2, ensure `pip install aws-cdk` is used instead and this V1 package is removed.","cause":"The `aws-cdk-custom-resources` package (or the monolithic `aws-cdk` for V2 projects) is not installed in the active Python environment, or there's a package version conflict.","error":"ModuleNotFoundError: No module named 'aws_cdk.custom_resources'"},{"fix":"Ensure all data passed in the custom resource's response is JSON serializable. Convert objects like `Decimal` or `datetime` to strings before including them in the response. For `AwsCustomResource`, verify parameters passed to SDK actions adhere to AWS API specifications.","cause":"A custom resource handler (especially Lambda-backed) attempted to return a non-JSON-serializable object in its response's `Data` field, or an SDK call's parameters were not correctly formatted.","error":"TypeError: Object of type Decimal is not JSON serializable (or similar for datetime, etc.)"},{"fix":"For `AwsCustomResource`, always set `physical_resource_id` using `PhysicalResourceId.of('your-stable-unique-id')`. For Lambda-backed `CustomResource`, ensure the Lambda function's response JSON includes a `PhysicalResourceId` field.","cause":"CloudFormation requires a unique and stable `PhysicalResourceId` to track custom resources. This error occurs when the custom resource (e.g., a Lambda-backed provider or an `AwsCustomResource` without a `physical_resource_id` parameter) fails to provide this identifier.","error":"Custom resource handler did not return a physical resource ID in the response."}]}