cloud-nuke Adds AWS Backup Plan Support And Hits An EFS Gotcha

   |   4 minute read   |   Using 739 words

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 is backup-plan.
  • Tag filtering does an extra ListTags call per plan. If you have thousands of plans, that is real cost. Skip it by leaving Tags empty on both rules.
  • The timeout field 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-type list, decide whether to add backup-plan to 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 with aws/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-plan first, then backup-vault, or expect the second pass to fail.
  • No new commits for BackupRecoveryPoint, BackupReportPlan, or BackupFramework in 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.



denis256 at denis256.dev