Skip to main content
discount · azure

Azure RI to Spot Migration for Non-Production

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

Reservation- or savings-plan-covered VMs with a positive non-production signal are candidates for Spot redeployment. The discount fraction is 1 minus the Spot-to-RI-1yr rate ratio, sanity-banded between 0.05 and 0.92; Windows/SQL Server, M-series, DR/standby, and stateful workloads are vetoed, and missing live rates cause abstention.

Signal and threshold

How ZopNight evaluates Azure RI to Spot Migration for Non-Production.
Field Value
Rule IDsRC-1381
Categorydiscount
Severitymedium
Metricnone — pure configuration read
Sourceri_to_spot.go

Reserved non-prod VMs that Spot can actually take

  • ReservationCoverage = Reservation/SavingsPlan (OnDemand VMs are RC-210’s); already-Spot skip; interruptible-lifecycle (Metadata[“lifecycle”]=spot/low_priority) false-RI-premise guard (fail-closed)
  • Positive non-prod signal (isNonProdResource, audit 2026-06-26 pattern A): gating on !isProdResource fired Spot on neutral-named prod VMs; abstains otherwise
  • M-series skip (isMSeriesVM, since Spot is unavailable); Databricks / VMSS-member skip. isVMSSMember only recognizes Uniform-orchestration members (nested …/virtualMachineScaleSets/…/virtualMachines/N UID); a Flexible-orchestration member is a flat Microsoft.Compute/virtualMachines UID linked via properties.virtualMachineScaleSet.id, which the discoverer does not currently stamp into Metadata, so such a member is not excluded today (audit 2026-07-01, low severity; a per-instance Spot migration on a Flex member is a policy-conflict risk with the scale set’s own scaling/HA policy, not a factually wrong claim). Extend the exclusion once the discoverer stamps VMSS-Flex membership.
  • stateful data-service veto (matchesStatefulWorkload)
  • critical-role name veto (#1906 B2): shares matchesCriticalRole (dr, standby, segment-boundary), and a DR/standby box is never migrated onto Spot.
  • OS/license veto (#1906 B4): shares isSpotIncompatibleOS, so Windows / SQL-Server (Metadata[“os_family”]/platform) are skipped; absent OS signal abstains.

The Spot to RI one-year rate ratio

cost-driven discount. The fraction is derived solely from live tier rates: frac = 1 − Spot/RI1yrNoUpfront, sanity-banded [0.05, 0.92] (riToSpotFractionFromTiers, rate-inversion guarded); SavingsUSD = cost × frac. The denominator is RI1yrNoUpfront (Aryan B3: the VM’s current cost is already RI-discounted, so OnDemand would over-state by the RI-discount fraction). The previous DeriveCommitmentToSpotFraction(…, azureRIToSpotSavingsFraction) flat 0.60 fallback is removed; when the aggregator has not priced this SKU’s RI1yr/Spot tiers (ok=false) or pricing is absent (cost ≤ 0) the rule abstains (returns nil), never falling back to a fabricated fraction.

Redeploying as Spot and freeing the reservation

  1. Confirm the workload tolerates interruption
  2. Re-deploy the VM as Spot priority
  3. Release the reservation back to the pool for production use

CPU and network as background evidence

CPUUtilization + VMNetworkIn (30d) are evidence only; the firing signal is structural (RI/SP coverage plus a positive non-prod signal)

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·