{"id":13563196,"url":"https://github.com/aws-cloudformation/custom-resource-helper","last_synced_at":"2025-05-14T13:06:01.718Z","repository":{"id":34290054,"uuid":"169458597","full_name":"aws-cloudformation/custom-resource-helper","owner":"aws-cloudformation","description":"Simplify best practice Custom Resource creation, sending responses to CloudFormation and providing exception, timeout trapping, and detailed configurable logging.","archived":false,"fork":false,"pushed_at":"2024-10-29T19:55:04.000Z","size":111,"stargazers_count":380,"open_issues_count":30,"forks_count":58,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-04-13T00:39:30.095Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aws-cloudformation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-06T18:53:12.000Z","updated_at":"2025-04-07T01:20:47.000Z","dependencies_parsed_at":"2024-11-08T12:29:12.238Z","dependency_job_id":"70828686-e57b-435b-badc-915e280534be","html_url":"https://github.com/aws-cloudformation/custom-resource-helper","commit_stats":{"total_commits":80,"total_committers":18,"mean_commits":4.444444444444445,"dds":0.575,"last_synced_commit":"f2095c5d11e5d3060f6e210b76313cea5f97bc8e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-cloudformation%2Fcustom-resource-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-cloudformation%2Fcustom-resource-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-cloudformation%2Fcustom-resource-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws-cloudformation%2Fcustom-resource-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aws-cloudformation","download_url":"https://codeload.github.com/aws-cloudformation/custom-resource-helper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254149948,"owners_count":22022851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:16.300Z","updated_at":"2025-05-14T13:06:01.610Z","avatar_url":"https://github.com/aws-cloudformation.png","language":"Python","funding_links":[],"categories":["Python","Custom Resource Development"],"sub_categories":["Hooks"],"readme":"## Custom Resource Helper\n\nSimplify best practice Custom Resource creation, sending responses to CloudFormation and providing exception, timeout \ntrapping, and detailed configurable logging.\n\n[![PyPI Version](https://img.shields.io/pypi/v/crhelper.svg)](https://pypi.org/project/crhelper/)\n![Python Versions](https://img.shields.io/pypi/pyversions/crhelper.svg)\n[![Build Status](https://travis-ci.com/aws-cloudformation/custom-resource-helper.svg?branch=main)](https://travis-ci.com/aws-cloudformation/custom-resource-helper)\n[![Test Coverage](https://codecov.io/gh/aws-cloudformation/custom-resource-helper/branch/main/graph/badge.svg)](https://codecov.io/gh/aws-cloudformation/custom-resource-helper)\n\n## Features\n\n* Dead simple to use, reduces the complexity of writing a CloudFormation custom resource\n* Guarantees that CloudFormation will get a response even if an exception is raised\n* Returns meaningful errors to CloudFormation Stack events in the case of a failure\n* Polling enables run times longer than the lambda 15 minute limit\n* JSON logging that includes request id's, stack id's and request type to assist in tracing logs relevant to a \nparticular CloudFormation event\n* Catches function timeouts and sends CloudFormation a failure response\n* Static typing (mypy) compatible\n \n## Installation\n\nInstall into the root folder of your lambda function\n\n```shell\ncd my-lambda-function/\npip install crhelper -t .\n```\n\n## Example Usage\n\n[This blog](https://aws.amazon.com/blogs/infrastructure-and-automation/aws-cloudformation-custom-resource-creation-with-python-aws-lambda-and-crhelper/) covers usage in more detail.\n\n```python\nfrom __future__ import print_function\nfrom crhelper import CfnResource\nimport logging\n\nlogger = logging.getLogger(__name__)\n# Initialise the helper, all inputs are optional, this example shows the defaults\nhelper = CfnResource(json_logging=False, log_level='DEBUG', boto_level='CRITICAL', sleep_on_delete=120, ssl_verify=None)\n\ntry:\n    ## Init code goes here\n    pass\nexcept Exception as e:\n    helper.init_failure(e)\n\n\n@helper.create\ndef create(event, context):\n    logger.info(\"Got Create\")\n    # Optionally return an ID that will be used for the resource PhysicalResourceId, \n    # if None is returned an ID will be generated. If a poll_create function is defined \n    # return value is placed into the poll event as event['CrHelperData']['PhysicalResourceId']\n    #\n    # To add response data update the helper.Data dict\n    # If poll is enabled data is placed into poll event as event['CrHelperData']\n    helper.Data.update({\"test\": \"testdata\"})\n\n    # To return an error to cloudformation you raise an exception:\n    if not helper.Data.get(\"test\"):\n        raise ValueError(\"this error will show in the cloudformation events log and console.\")\n    \n    return \"MyResourceId\"\n\n\n@helper.update\ndef update(event, context):\n    logger.info(\"Got Update\")\n    # If the update resulted in a new resource being created, return an id for the new resource. \n    # CloudFormation will send a delete event with the old id when stack update completes\n\n\n@helper.delete\ndef delete(event, context):\n    logger.info(\"Got Delete\")\n    # Delete never returns anything. Should not fail if the underlying resources are already deleted.\n    # Desired state.\n\n\n@helper.poll_create\ndef poll_create(event, context):\n    logger.info(\"Got create poll\")\n    # Return a resource id or True to indicate that creation is complete. if True is returned an id \n    # will be generated\n    return True\n\n\ndef handler(event, context):\n    helper(event, context)\n```\n\n### Polling\n\nIf you need longer than the max runtime of 15 minutes, you can enable polling by adding additional decorators for \n`poll_create`, `poll_update` or `poll_delete`. When a poll function is defined for `create`/`update`/`delete` the \nfunction will not send a response to CloudFormation and instead a CloudWatch Events schedule will be created to \nre-invoke the lambda function every 2 minutes. When the function is invoked the matching `@helper.poll_` function will \nbe called, logic to check for completion should go here, if the function returns `None` then the schedule will run again \nin 2 minutes. Once complete either return a PhysicalResourceID or `True` to have one generated. The schedule will be \ndeleted and a response sent back to CloudFormation. If you use polling the following additional IAM policy must be \nattached to the function's IAM role:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"lambda:AddPermission\",\n        \"lambda:RemovePermission\",\n        \"events:PutRule\",\n        \"events:DeleteRule\",\n        \"events:PutTargets\",\n        \"events:RemoveTargets\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n### Certificate Verification\nTo turn off certification verification, or to use a custom CA bundle path for the underlying boto3 clients used by this library, override the `ssl_verify` argument with the appropriate values.  These can be either:\n* `False` - do not validate SSL certificates. SSL will still be used, but SSL certificates will not be verified.\n* `path/to/cert/bundle.pem` - A filename of the CA cert bundle to uses. You can specify this argument if you want to use a different CA cert bundle than the one used by botocore.\n\n### Use CDK to depoy a Custom Resource that uses Custom Resource Helper\n\nYou can use the [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) to deploy a Custom Resource that uses Custom Resource Helper. AWS CDK is an open-source software development framework for defining cloud infrastructure in code and provisioning it through AWS CloudFormation.\n\n**Note**: `crhelper` is not intended to be used with AWS CDK using the [Provider](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources.Provider.html) construct.\n\n#### AWS CDK template example\n```\nfrom aws_cdk import (\n    ...\n    aws_lambda as _lambda,\n    CustomResource,\n)\n\ncrhelperSumResource = _lambda.Function(...)\n\ncustomResource = CustomResource(\n  self, \n  'MyCustomResource'\n  serviceToken = crhelperSumResource.function_arn,\n  properties = {\n    'No1': 1,\n    'No2': 2\n  },\n)\n\n\n```\n\n## Credits\n\nDecorator implementation inspired by https://github.com/ryansb/cfn-wrapper-python\n\nLog implementation inspired by https://gitlab.com/hadrien/aws_lambda_logging\n\n## License\n\nThis library is licensed under the Apache 2.0 License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws-cloudformation%2Fcustom-resource-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faws-cloudformation%2Fcustom-resource-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws-cloudformation%2Fcustom-resource-helper/lists"}