{ "info": { "author": "Jay McConnell", "author_email": "jmmccon@amazon.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "## 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=master)](https://travis-ci.com/aws-cloudformation/custom-resource-helper)\n[![Test Coverage](https://img.shields.io/codecov/c/github/aws-cloudformation/custom-resource-helper.svg)](https://codecov.io/github/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\n## Installation\n\nInstall into the root folder of your lambda function\n\n```json\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')\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 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. CloudFormation will send\n # 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. 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 will be generated\n return True\n\n\ndef handler(event, context):\n helper(event, context)\n\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```yaml\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\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\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/aws-cloudformation/custom-resource-helper", "keywords": "", "license": "Apache2", "maintainer": "", "maintainer_email": "", "name": "crhelper", "package_url": "https://pypi.org/project/crhelper/", "platform": "", "project_url": "https://pypi.org/project/crhelper/", "project_urls": { "Homepage": "https://github.com/aws-cloudformation/custom-resource-helper" }, "release_url": "https://pypi.org/project/crhelper/2.0.4/", "requires_dist": [ "requests" ], "requires_python": "", "summary": "crhelper simplifies authoring CloudFormation Custom Resources", "version": "2.0.4" }, "last_serial": 5788950, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "d69d49a72ac8875f4c0bddaa73993add", "sha256": "0a4291c98b4500f7d4c030fdf15fcdd4c1f17d2887239d94b8c66f7e2eb2472f" }, "downloads": -1, "filename": "crhelper-1.0.0.tar.gz", "has_sig": false, "md5_digest": "d69d49a72ac8875f4c0bddaa73993add", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2208, "upload_time": "2018-11-12T15:50:57", "url": "https://files.pythonhosted.org/packages/8d/14/505b6d8ed15735792e6622bc997ca21908c8bb817b42b2dfb600b7cb2c13/crhelper-1.0.0.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "8b958a0522fbf3a1105530510dd239c1", "sha256": "beeb81dbc98ab3e11dec64b19f37290cfa5ac51f10fa10da5c6ef264d039265b" }, "downloads": -1, "filename": "crhelper-2.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8b958a0522fbf3a1105530510dd239c1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15382, "upload_time": "2019-03-07T18:22:34", "url": "https://files.pythonhosted.org/packages/64/4d/d13272e7663bf1f3db5099feb07b8fac7ef24cdc8e05d31df35aa135e678/crhelper-2.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "18c17e4d8cf1a3781b8101bc80131867", "sha256": "681804bd2b4b1c875df003ad46e5e3cb6a19dc99279a098fe462f289f0d26400" }, "downloads": -1, "filename": "crhelper-2.0.0.tar.gz", "has_sig": false, "md5_digest": "18c17e4d8cf1a3781b8101bc80131867", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9698, "upload_time": "2019-03-07T18:22:36", "url": "https://files.pythonhosted.org/packages/ff/b8/1352cad63868c17ce37e06074e62ba0b38451d9060ec86065c506cf704e5/crhelper-2.0.0.tar.gz" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "a6babf77ae06bb79edef153f24d9c255", "sha256": "e143234687c61e373603145d2e4fd0beac432443e4e14bcf320e84f12bf99d50" }, "downloads": -1, "filename": "crhelper-2.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a6babf77ae06bb79edef153f24d9c255", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15376, "upload_time": "2019-03-07T18:30:46", "url": "https://files.pythonhosted.org/packages/27/2f/5558cfd1e7a6b45318468c847953f4e139b2e6c75f686b6c0c8e72d77918/crhelper-2.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d5215a62a6fdca38274eac9d63e8c46c", "sha256": "5e9f63879132d74c0abf60bc14c8f6c36bf67d50b4549e2d4b5017de0c3e41bb" }, "downloads": -1, "filename": "crhelper-2.0.1.tar.gz", "has_sig": false, "md5_digest": "d5215a62a6fdca38274eac9d63e8c46c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9702, "upload_time": "2019-03-07T18:30:48", "url": "https://files.pythonhosted.org/packages/83/d1/8c0c4924454242cee0c80c7ffd24c99464e65d2659d1747897cac7e8c942/crhelper-2.0.1.tar.gz" } ], "2.0.2": [ { "comment_text": "", "digests": { "md5": "fc72181aa7026ce8ad488072fbc99325", "sha256": "cc7d5c4eaf35a3bd6a2de07682d7dd96857660d25f0fd7c876647e6f730f2bdf" }, "downloads": -1, "filename": "crhelper-2.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "fc72181aa7026ce8ad488072fbc99325", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15493, "upload_time": "2019-03-08T00:10:34", "url": "https://files.pythonhosted.org/packages/9a/91/e397d881a8e5e539c9de0de70096852b9a245a9be8f37012e894e4cd3aec/crhelper-2.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cc07440dcbf5a15cd36e5b2249bbaf30", "sha256": "ca39df96fd14cf8edc1fa69b0d459b59dd77d617138555a3f429234d6f930f72" }, "downloads": -1, "filename": "crhelper-2.0.2.tar.gz", "has_sig": false, "md5_digest": "cc07440dcbf5a15cd36e5b2249bbaf30", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9848, "upload_time": "2019-03-08T00:10:35", "url": "https://files.pythonhosted.org/packages/a6/d8/9f77dee72f808a48ca2df7e76940d5da7de6d985e985cae70aef343cd7c3/crhelper-2.0.2.tar.gz" } ], "2.0.3": [ { "comment_text": "", "digests": { "md5": "fdd5e833562f943db52194dae96959a5", "sha256": "66f8c85ef7461615c85f208d1948db386171a199d061503b5bce62552a9c6e21" }, "downloads": -1, "filename": "crhelper-2.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "fdd5e833562f943db52194dae96959a5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15793, "upload_time": "2019-05-20T16:30:54", "url": "https://files.pythonhosted.org/packages/36/30/d907569254d94f4009f52f2078f4ba4a46a890494e69ce226d2d38c9739f/crhelper-2.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2c831803cc6987ead7f43ae3174308f1", "sha256": "cb6f81b503e1fb215aba381d964d484dbd45c2c93950090be3b62f6b37f45a19" }, "downloads": -1, "filename": "crhelper-2.0.3.tar.gz", "has_sig": false, "md5_digest": "2c831803cc6987ead7f43ae3174308f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10659, "upload_time": "2019-05-20T16:30:55", "url": "https://files.pythonhosted.org/packages/41/0e/d8ae2b11746348057394f5c12f512e96c997672b872fbbe8aa52cdcfb5f2/crhelper-2.0.3.tar.gz" } ], "2.0.4": [ { "comment_text": "", "digests": { "md5": "f47141a4b4552833a133f26c865ab860", "sha256": "d5bc01b488bc6311087db6a030623663a1c50a0cd295dc4cd03bb4de5b55df92" }, "downloads": -1, "filename": "crhelper-2.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "f47141a4b4552833a133f26c865ab860", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15890, "upload_time": "2019-09-05T23:38:44", "url": "https://files.pythonhosted.org/packages/00/1b/0082728aad953056411557080f4cd8b9d8c4d49a093c6cee7d009fcbe4a2/crhelper-2.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2f58e01a2a2980dc714922a223e1aa75", "sha256": "39090fc75149c27db8e0fb052e1a8a11f06c8f015fa6d34441cf7fc28b729cc6" }, "downloads": -1, "filename": "crhelper-2.0.4.tar.gz", "has_sig": false, "md5_digest": "2f58e01a2a2980dc714922a223e1aa75", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10817, "upload_time": "2019-09-05T23:38:46", "url": "https://files.pythonhosted.org/packages/ad/21/a4554a7f621ca61215cf57065bd08a8e5575cfcd3187a122a80f3bf03bae/crhelper-2.0.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f47141a4b4552833a133f26c865ab860", "sha256": "d5bc01b488bc6311087db6a030623663a1c50a0cd295dc4cd03bb4de5b55df92" }, "downloads": -1, "filename": "crhelper-2.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "f47141a4b4552833a133f26c865ab860", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15890, "upload_time": "2019-09-05T23:38:44", "url": "https://files.pythonhosted.org/packages/00/1b/0082728aad953056411557080f4cd8b9d8c4d49a093c6cee7d009fcbe4a2/crhelper-2.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2f58e01a2a2980dc714922a223e1aa75", "sha256": "39090fc75149c27db8e0fb052e1a8a11f06c8f015fa6d34441cf7fc28b729cc6" }, "downloads": -1, "filename": "crhelper-2.0.4.tar.gz", "has_sig": false, "md5_digest": "2f58e01a2a2980dc714922a223e1aa75", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10817, "upload_time": "2019-09-05T23:38:46", "url": "https://files.pythonhosted.org/packages/ad/21/a4554a7f621ca61215cf57065bd08a8e5575cfcd3187a122a80f3bf03bae/crhelper-2.0.4.tar.gz" } ] }