cloud-nuke Adds AWS Backup Plan Support And Hits An EFS Gotcha
cloud-nuke is the AWS resource cleanup tool from Gruntwork. The last week brought one feature commit and one quick CI follow up, both about the same thing: AWS Backup Plans are now a supported resource type, and the team caught the inevitable side effect within a day.
The new backup-plan resource
Most of the week’s diff sits in one commit, add BackupPlan support, which lands a fresh resource called backup-plan. The implementation lives in aws/resources/backup_plan.go and follows the same generic resource pattern that the rest of the catalog uses.
The lister calls ListBackupPlans, optionally enriches each plan with tags via ListTags, and runs the standard config filter (ShouldInclude) so name regex, time windows, and tag rules work out of the box. The nuker is a MultiStepDeleter: it walks ListBackupSelections for the plan and deletes every selection first, then deletes the plan itself. That order matters. DeleteBackupPlan returns an error if selections still exist.
The resource is wired into the registry in aws/resource_registry.go right next to BackupVault. A new Config.BackupPlan field shows up in config/config.go and joins allResourceTypes() so the same filtering logic applies as for every other resource type.
The test file aws/resources/backup_plan_test.go is 301 lines and covers listing, tag enrichment, and the multi step delete path against a mock API. It mirrors the shape of other resource tests in the repo.
What the config looks like
The example in config/examples/complete.yaml gives you the full filter shape, and it is intentionally identical to the other AWS resource blocks.
BackupPlan:
include:
names_regex:
- that.*
time_after: 2024-02-02T00:00:00Z
tags:
test: "true"
exclude:
names_regex:
- this.*
timeout: 1h
protect_until_expire: true
Filter support covers name regex, time window, tags, and protect_until_expire. The CLI key for the resource is backup-plan, and it now appears in docs/supported-resources.md with all four filter columns checked.
A few practical notes for anyone wiring this in:
- The key in YAML is
BackupPlan(CamelCase), the CLI identifier isbackup-plan. - Tag filtering does an extra
ListTagscall per plan. If you have thousands of plans, that is real cost. Skip it by leavingTagsempty on both rules. - The
timeoutfield applies per resource as usual.
The AWS managed EFS plan that broke the cron
This is the part anyone running cloud-nuke on a schedule should read. One day after the feature merged, the team shipped a CI exclusion for the AWS managed EFS backup plan. The commit message is honest about why: the PhxDevOps cron started failing in us-east-1 because the new resource immediately picked up the service managed aws/efs/<uuid> plan that AWS Backup creates for EFS volumes when automatic backups are on. DeleteBackupSelection returns 403 on those because AWS Backup, not your account, owns the selection.
The fix is a name regex exclude in .github/nuke_config.yml that mirrors the existing BackupVault exclude for the same family.
BackupPlan:
exclude:
names_regex:
# AWS-managed EFS automatic backup plan
- "^aws/efs/.*"
If you are about to turn on backup-plan in your own cleanup config, copy that regex. The same trap already exists on BackupVault and there is no AWS API field that says “this is service owned versus user owned” on a plan. Name pattern is the only thing you have.
Worth calling out: the upstream Go code itself does not skip AWS managed plans automatically. The exclusion lives in the project’s own CI config, not in the resource implementation. If you want the same protection in your runs, you have to put the regex into your own config.
What to watch
- If your wrapper script uses a hardcoded
--resource-typelist, decide whether to addbackup-planto it. The tool will not nuke a resource type that is not enabled, but the new key is now valid. - The EFS exclusion regex is
^aws/efs/.*. Plan names from your own backup workflows that happen to begin withaws/efs/would be matched too, which is unlikely but worth a glance. - Order matters when you nuke both plans and vaults. Plans reference recovery points and selections, vaults hold the actual data. Run with
backup-planfirst, thenbackup-vault, or expect the second pass to fail. - No new commits for
BackupRecoveryPoint,BackupReportPlan, orBackupFrameworkin this window. If you need those, that is still your own scripting problem.
Where to read more: the project lives at gruntwork-io/cloud-nuke. The two commits in this window are the feature add and the CI exclusion that followed it. Both are short, both are worth a look before you enable the new resource type in production.