# PLAT-86 CFN dispose runbook (import-in-place) Prerequisites (already proven 2026-08-07): - HCP workspace `procurement-ingest-prod` Manual apply green; verification plan **0/0/0** - Lambdas on `/tf-managed/` roles - TF owns `aws_s3_bucket_notification` on both email buckets (`*-inbound` ids) - Soft-freeze replaced by hard-cut (`.github/workflows/deploy.yaml` removed) - Smoke green for `po-email-processor`, `workorder-email-processor`, `procurement-api` ## Rule Never run `cfn-stack-decommission.sh --execute` against these stacks. That script purges RETAIN orphans after delete. Here RETAIN orphans are the live TF-owned data plane. ## Method 1. **Retain-all update** — for each stack (`po-ingest`, `WorkorderIngestStack`, `procurement-api`), set `DeletionPolicy: Retain` and `UpdateReplacePolicy: Retain` on every resource in the live template, then `update-stack`. This includes `Custom::S3BucketNotifications` so CFN will not invoke the empty `PutBucketNotificationConfiguration` delete handler. 2. **Delete stack** — `delete-stack` after `UPDATE_COMPLETE`. All resources leave CFN without destruction. 3. **Verify immediately** — `GetBucketNotificationConfiguration` still lists inbound Lambda triggers; SES receipt rules for PO/WO still present on `INBOUND_MAIL`; named Lambdas/tables/buckets still exist; smoke script green. 4. **Sweep CDK helpers only** — delete orphaned `*BucketNotificationsHandler*` Lambda functions and their IAM roles/policies (both stacks). Do not delete TF-owned Lambdas, tables, buckets, API GW, SES rules, or SHOC secret/KMS. 5. **Park** `githubdeploy-procurement-ingest` for a separate IAM-reviewed cleanup (do not block dispose). ## Script `scripts/plat86-cfn-dispose.sh` implements steps 1–4 with explicit confirms and post-checks. Retain-all templates exceed the CloudFormation CLI 51KB inline `--template-body` limit, so the script stages them to `s3://procurement-ingest-artifacts-011934824531/plat86-cfn-dispose/` and updates via `--template-url`.