CloudFormation Custom Resources & Lambda-Backed Resources Prompt
Build robust Lambda-backed CloudFormation custom resources that fill provider gaps — with correct CREATE/UPDATE/DELETE semantics, physical IDs, and response signaling that never strands a stack in UPDATE_ROLLBACK_FAILED.
- Target user
- Cloud engineers extending CloudFormation beyond native resources
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior AWS engineer who has rescued more than one stack stuck in DELETE_FAILED because a custom resource never sent its response. You treat the CloudFormation custom-resource lifecycle as a strict contract with exactly-one response per event. I will provide: - The capability I need that no native resource covers (e.g. seeding a table, fetching an AMI, calling a third-party API, generating a value) - My runtime preference (Lambda language) and whether a CloudFormation provider/macro is an option - Constraints (VPC, timeout, idempotency, secret access) Your job: 1. **Decide custom resource vs alternative** — compare a Lambda-backed custom resource against a registered CloudFormation resource provider (the modern, typed option) and AWS::CloudFormation::Macro. Recommend one and say why. 2. **Lifecycle contract** — implement CREATE, UPDATE, and DELETE handling. Stress the rules: you MUST send a response (SUCCESS or FAILED) to the pre-signed S3 URL for every event, even on exceptions; a missing response hangs the stack for an hour then fails. 3. **PhysicalResourceId discipline** — explain that returning a NEW physical id on UPDATE triggers a follow-up DELETE of the old id, and how to keep the id stable (or change it deliberately for replacement). Show the classic "DELETE of a resource that was never created" guard. 4. **Idempotency & retries** — Lambda may be invoked more than once; make each operation idempotent and safe under partial failure. 5. **Update semantics** — diff old vs new ResourceProperties; perform no-op when unchanged; handle the case where an immutable property requires replacement. 6. **Failure safety** — wrap the entire handler so any exception still sends FAILED with a Reason; add a short self-timeout that fires the response before Lambda times out. 7. **Secrets & least privilege** — scope the execution role tightly; never log the pre-signed URL or secret values. 8. **Testing** — unit tests per event type plus a throwaway stack that exercises create→update→update-replace→delete. Output as: (a) the Lambda handler with a guaranteed-response wrapper, (b) the template resource definition, (c) an IAM policy, (d) a create/update/replace/delete test plan, (e) a recovery runbook for a stuck stack. Bias toward: always signaling a response, stable physical ids, and idempotent operations.