Add soft-delete detection preflight to prevent FlagMustBeSetForRestore failures
- Dominant language
- Go
- Stars
- 569
- Forks
- 364
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 136
Description
## Problem
`FlagMustBeSetForRestore` accounts for **372 ARM deployment failures per month** (7.9% of all `InvalidTemplateDeployment` errors) across 132 unique machines. Users deploy to a resource name that was previously soft-deleted, ARM requires `createMode: restore` or an explicit purge, and azd handles neither.
### Telemetry Data (March 2026, 23 days)
| Error Code | Count | Avg Wait | Service |
|---|---|---|---|
| FlagMustBeSetForRestore | 330 | 256s | Container Apps (74), Functions (56), Key Vault, Cognitive Services |
| CanNotRestoreAnActiveResource | 27 | — | Mixed |
| CanNotRestoreANonExistingResource | 15 | — | Mixed |
| **Total** | **372** | **242s avg** | **25 user-hours wasted/month** |
### User Impact
- Users wait an average of **4 minutes** before receiving a soft-delete error
- **65% retry without changing anything** — retrying can never work without purging or restoring
- These errors are **100% preventable** with a preflight check
### Proposed Solution
Add a preflight check in the provisioning pipeline that:
1. Extracts resource names from the Bicep snapshot for soft-delete-capable resource types:
- `Microsoft.KeyVault/vaults` — [List Deleted Vaults API](https://learn.microsoft.com/en-us/rest/api/keyvault/vaults/list-deleted)
- `Microsoft.CognitiveServices/accounts` — [List Deleted Accounts API](https://learn.microsoft.com/en-us/rest/api/cognitiveservices/accountmanagement/deleted-accounts/list)
- `Microsoft.ApiManagement/service` — [List Deleted Services API](https://learn.microsoft.com/en-us/rest/api/apimanagement/deleted-services/list-by-subscription)
- `Microsoft.App/managedEnvironments` — check via resource existence
2. If a name collision with a soft-deleted resource is found, prompt the user:
- **Purge** — permanently delete the soft-deleted resource and proceed
- **Restore** — recover the previous resource instead of creating new
- **Rename** — use a different resource name
3. This check runs alongside existing preflight checks (policy check in #7179, quota check in #6800)
### Related
- #6800 — Quota preflight (same pipeline integration point)
- #7179 — Policy preflight (same architectural pattern)
- #7115 — Never abort on validation errors (UX alignment)
Contributor guide
Assessment
This issue has not been assessed yet.