Azure Recovery Vault Soft-Delete Retention Tune
What does ZopNight detect here?
Detection flags Recovery Services vaults whose soft-delete retention exceeds the 14-day baseline, but the rule abstains from any dollar figure today: soft-deleted byte volume and a per-GB backup-storage rate are both unmeasured, and the former hardcoded 10% storage-share estimate was removed rather than fabricate savings.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1385 |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Source | recovery_vault_soft_delete.go |
Where it applies
Soft-delete windows past the 14-day baseline
- Metadata soft_delete_enabled == “true” (feature on; disabled/unknown => abstain)
- Metadata soft_delete_retention_days (from BackupResourceVaultConfig) > 14-day baseline (recoveryVaultBaselineSoftDeleteDays)
Why soft-deleted bytes cannot be priced
the cost/soft_delete_enabled/retention>baseline gates confirm the over-baseline window, but the rule abstains (returns nil). The real saving is cost × soft-delete-storage-share × (1 − 14/retentionDays), and the share is exactly the unmeasured volume of soft-deleted backup bytes. The prior hardcoded 10% share fraction (recoveryVaultSoftDeleteSavingsFraction, deleted from constants.go) is removed; a $0 rec under the cost-driven rightsizing category is dropped by shouldDropLowSavings anyway. PRODUCER-GAP: soft-deleted byte volume is not lightweight-obtainable; two independent inputs are missing:
- Soft-deleted byte volume. The discoverer already paginates BackupProtectedItems.List (recovery_vault_backup_client.go fetchProtectedItemsSummary) and can read soft-delete state per item for free (base ProtectedItem carries IsScheduledForDeferredDelete + ResourceState=SoftDeleted + DeferredDeleteTimeRemaining). But the base ProtectedItem carries no occupied-bytes field. DiskStorageUsedInBytes/TotalDiskStorageSizeInBytes live only on DPMProtectedItemExtendedInfo (on-prem DPM/MABS), and RecoveryPointSizeInGB only on AzureFileShareRecoveryPoint. Sizing soft-deleted items needs a per-item RecoveryPoints.List enumeration (N items × M recovery points), a heavy scan that does not fit the discoverer’s 7-req/5-sec shared limiter. BackupUsageSummaries.List is vault-level total storage only, with no soft-deleted-vs-active split.
- Per-GB Azure-Backup-storage rate. The aggregator pricing feed collapses every “Azure Backup” meter (protected-instance + LRS/GRS/ZRS per-GB storage) into a single lowest-rate-wins recovery-vault key (backend/aggregator/internal/pricing/azure/pricing.go case “Azure Backup”: return “recovery-vault”), so there is no isolated per-GB backup-storage rate.
Shortening the window if policy allows
(unused; abstains)
- Review compliance constraints before shortening the window
- Reduce soft-delete retention to the minimum allowed value
- Purge orphaned soft-deleted items manually if policy blocks auto-cleanup