AWS account and resource decommissioning

How to prove something is unused, retire it in reversible stages and close an AWS account without breaking a hidden dependency.

Updated 2026-11-11Raw markdown

Strategy sections
On this page

Use this page for retiring a stack, a service, a VPC, a set of resources or a whole account. Decommissioning saves money and shrinks the attack surface, but deleting something that was quietly in use causes an outage you cannot easily undo.

Stage it: prove, isolate, wait, delete

flowchart LR
  P[Prove unused] --> O[Owner signs off]
  O --> S[Scream test: disable or isolate]
  S --> W[Wait 2-4 weeks]
  W --> B[Final backup or snapshot]
  B --> D[Delete via IaC MR]
  D --> C[Close account if empty]

Prove it is unused

  • Traffic: load balancer and API gateway request counts for 30 days.
  • Compute: CPU and network on instances and tasks; Lambda invocations.
  • Data: database connections, S3 request metrics or access logs, queue message counts.
  • Callers: CloudTrail for API calls into the resources from other accounts or roles.
  • Network: VPC flow logs, peering and transit gateway attachments, routes that point into this VPC.
  • DNS: records in any zone that point at these resources.
  • Code and config: search repos and CI for names, ARNs and hostnames.
  • Scheduled jobs and EventBridge rules that target these resources.

Recipes for each are in AWS read-only investigation. Write the evidence into the ticket as a table.

Rate the risk of each piece

Piece Risk Why
Stopped instances, unattached volumes, old snapshots Low Nothing routes to them
Sandbox stacks, unused DNS names Low Non-production
Parameters and secrets Medium Something may read them at start-up
Route tables, subnets, peering, transit attachments High Other networks may route through them
Databases and buckets with data High Data loss is permanent; check retention rules

Do the low-risk pieces first, as separate tickets.

Scream test

  • Stop instances, scale services to zero, detach a route, or deny access with a policy, rather than deleting.
  • Announce the date and who to contact.
  • Wait long enough to cover monthly jobs and month-end reporting.

Delete

  • Final snapshot or export where retention rules require it, tagged with the ticket and a delete-after date.
  • Remove through Terraform in an MR (see Terraform changes). For resources not in code, write the exact CLI commands into the MR or ticket for review first.
  • Remove DNS records, monitors, dashboards, alerts and CI jobs that referenced it.

Close an AWS account

  • Account is empty of billable resources in every region (check Cost Explorer for the last 30 days by service).
  • No one still uses it for log archives, backups or cross-account roles.
  • Root user email and MFA are under team control.
  • Close through AWS Organizations by the organization admin. The account is suspended for 90 days, then permanently closed; it can be reopened during that window.
  • Remove it from SSO assignments, inventories, monitoring and the account list.

Pitfalls

  • "Suspended" is not "closed". Track the account until the 90 days pass.
  • Deleting the KMS key that encrypts backups you kept. Schedule key deletion last, with the longest waiting period.
  • Assuming a sandbox name means sandbox. Check what actually routes to it.
  • Quarantined or legal-hold accounts are out of scope until someone with authority says otherwise.