Azure Non-Prod Premium Disk Downgrade
What does ZopNight detect here?
Non-production Premium_LRS managed disks of 32 GB or larger are candidates for a Standard SSD tier downgrade at the same size. Savings use the real per-hour tier-rate delta times 730 hours; database-role disk names are vetoed, and the rule abstains when either tier rate is missing.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1386 |
| Category | rightsizing |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | disk_tier_downgrade.go |
Where it applies
Non-prod Premium_LRS disks that are not DB volumes
- resource.InstanceType = Premium_LRS; resource.SizeGB ≥ azureDiskDowngradeMinSizeGB (P4 / ≥32GB).
- POSITIVE non-prod signal via isNonProdResource (audit 2026-06-26 pattern A: gating on !isProdResource flagged production SQL-Server disks). Abstains unless non-prod is positively established.
- DB-role name veto (matchesDBRoleDiskName, covering datadisk/logdisk/tempdb/sql/oracle/hana): never downgrade a Premium DB-role volume’s tier (I/O SLA risk).
- per-size Premium + StandardSSD tier rates in pricing_cache for the region.
The tier rate delta priced over 730 hours
Real per-hour tier-rate delta: savings = (srcRate − dstRate) × 730 (managed disks bill per provisioned hour). The rule abstains (returns nil) when either tier rate is absent, dstRate ≥ srcRate, the result is ≤ 0, or savings ≥ cost (an at/above-cost delta signals a stale/anomalous rate, not a real saving). The pre-fix azureDiskDowngradeSavingsFraction × cost fabrication (it fired on every rec because the tier keys were never fetched) was removed, leaving no fabricated flat fraction (concrete-or-abstain, 2026-06-27). Description interpolates the rate-derived figure (resolves the old prose/compute “~40%” divergence).
Snapshot, deallocate, then switch the tier
- Confirm the disk is non-production;
- snapshot;
- stop/deallocate the VM;
- change to StandardSSD_LRS at the same size;
- validate performance
Read and write ops as an IOPS-starvation veto
DiskDataReadOps + DiskDataWriteOps (30d, declared) are not a firing gate (the rule fires on SKU + environment + size, distinct from RC-1394): when both series are present and the observed peak (sum of per-series maxima) exceeds the target StandardSSD tier’s IOPS ceiling for the size, the downgrade would IOPS-starve the workload => abstain (2026-07-02 safety veto for the non-guided hot resize); absent series keeps the environment-basis fire