Skip to content

Commit ecf69e8

Browse files
authored
Merge pull request #1237 from paragpatil1999/feature/vmss-rolling-upgrade-policy
Virtual Machine Scale Sets: Add support for rolling upgrade policy configuration.
2 parents d408f18 + a333233 commit ecf69e8

File tree

5 files changed

+511
-0
lines changed

5 files changed

+511
-0
lines changed

RELEASE_NOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
Release Notes
22
=============
33

4+
## 1.9.26
5+
* Virtual Machine Scale Sets: Add support for rolling upgrade policy configuration.
6+
47
## 1.9.25
58
* Service Bus: Support for minimum TLS version of 1.3.
69
* Storage Accounts: Support for requesting minimum TLS version of 1.3. The ARM resource itself currently falls back to 1.2.

docs/content/api-overview/resources/vm-scale-set.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ The Virtual Machine Scale Set builder (`vmss`) creates a virtual machine scale s
3232
| vmss | osupgrade_automatic_rollback | Whether OS image rollback feature should be enabled. Enabled by default. |
3333
| vmss | osupgrade_rolling_upgrade | Indicates whether rolling upgrade policy should be used during Auto OS Upgrade. Default value is false. Auto OS Upgrade will fallback to the default policy if no policy is defined on the VMSS. |
3434
| vmss | osupgrade_rolling_upgrade_deferral | Indicates whether Auto OS Upgrade should undergo deferral. Deferred OS upgrades will send advanced notifications on a per-VM basis that an OS upgrade from rolling upgrades is incoming, via the IMDS tag 'Platform.PendingOSUpgrade'. The upgrade then defers until the upgrade is approved via an ApproveRollingUpgrade call. |
35+
| vmss | rolling_upgrade_enable_cross_zone_upgrade | Allow VMSS to ignore Availability Zone boundaries when constructing upgrade batches. Allows Azure to spread out batches across different zones. |
36+
| vmss | rolling_upgrade_max_batch_instance_percent | The maximum percentage of total virtual machine instances that will be upgraded simultaneously by the rolling upgrade in one batch. Should be between 5 and 100. |
37+
| vmss | rolling_upgrade_max_surge | Create new instances temporarily to replace old ones during upgrade. Helps maximize availability during rolling upgrades. |
38+
| vmss | rolling_upgrade_max_unhealthy_instance_percent | The maximum percentage of the total virtual machine instances in the scale set that can be simultaneously unhealthy before the rolling upgrade aborts. |
39+
| vmss | rolling_upgrade_max_unhealthy_upgraded_instance_percent | The maximum percentage of upgraded virtual machine instances that can be found to be in an unhealthy state. |
40+
| vmss | rolling_upgrade_pause_time_between_batches | The wait time between completing the update for all virtual machines in one batch and starting the next batch. The time duration should be specified in ISO 8601 format (e.g. PT5M for 5 minutes). |
41+
| vmss | rolling_upgrade_prioritize_unhealthy_instances | Upgrade all unhealthy instances in a scale set before any healthy instances. |
42+
| vmss | rolling_upgrade_rollback_failed_instances_on_policy_breach | Rollback failed instances to previous model if the Rolling Upgrade policy is violated. |
3543
| applicationHealthExtension | vmss | When adding the extension as a resource, this specifies the VM scale set it should be applied to. |
3644
| applicationHealthExtension | os | Operating system (Linux or Windows) to install the correct extension for that OS. |
3745
| applicationHealthExtension | protocol | Protocol (TCP, HTTP, or HTTPS) to probe, and if specifying HTTP or HTTPS, include the path. |

src/Farmer/Arm/Compute.fs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,52 @@ type VmssAutomaticOSUpgradePolicy = {
733733
UseRollingUpgradePolicy = None
734734
}
735735

736+
type VmssRollingUpgradePolicy = {
737+
EnableCrossZoneUpgrade: bool option
738+
MaxBatchInstancePercent: int option
739+
MaxSurge: bool option
740+
MaxUnhealthyInstancePercent: int option
741+
MaxUnhealthyUpgradedInstancePercent: int option
742+
PauseTimeBetweenBatches: TimeSpan option
743+
PrioritizeUnhealthyInstances: bool option
744+
RollbackFailedInstancesOnPolicyBreach: bool option
745+
} with
746+
747+
member this.ArmJson = {|
748+
enableCrossZoneUpgrade = this.EnableCrossZoneUpgrade |> Option.toNullable
749+
maxBatchInstancePercent = this.MaxBatchInstancePercent |> Option.toNullable
750+
maxSurge = this.MaxSurge |> Option.toNullable
751+
maxUnhealthyInstancePercent = this.MaxUnhealthyInstancePercent |> Option.toNullable
752+
maxUnhealthyUpgradedInstancePercent = this.MaxUnhealthyUpgradedInstancePercent |> Option.toNullable
753+
pauseTimeBetweenBatches =
754+
this.PauseTimeBetweenBatches
755+
|> Option.map (fun ts -> (IsoDateTime.OfTimeSpan ts).Value)
756+
|> Option.toObj
757+
prioritizeUnhealthyInstances = this.PrioritizeUnhealthyInstances |> Option.toNullable
758+
rollbackFailedInstancesOnPolicyBreach = this.RollbackFailedInstancesOnPolicyBreach |> Option.toNullable
759+
|}
760+
761+
static member Default = {
762+
EnableCrossZoneUpgrade = None
763+
MaxBatchInstancePercent = None
764+
MaxSurge = None
765+
MaxUnhealthyInstancePercent = None
766+
MaxUnhealthyUpgradedInstancePercent = None
767+
PauseTimeBetweenBatches = None
768+
PrioritizeUnhealthyInstances = None
769+
RollbackFailedInstancesOnPolicyBreach = None
770+
}
771+
736772
type ScaleSetUpgradePolicy = {
737773
Mode: VmScaleSet.UpgradeMode
738774
AutomaticOSUpgradePolicy: VmssAutomaticOSUpgradePolicy option
775+
RollingUpgradePolicy: VmssRollingUpgradePolicy option
739776
} with
740777

741778
static member Default = {
742779
Mode = VmScaleSet.UpgradeMode.Automatic
743780
AutomaticOSUpgradePolicy = None
781+
RollingUpgradePolicy = None
744782
}
745783

746784
member this.ArmJson = {|
@@ -749,6 +787,10 @@ type ScaleSetUpgradePolicy = {
749787
this.AutomaticOSUpgradePolicy
750788
|> Option.map _.ArmJson
751789
|> Option.defaultValue Unchecked.defaultof<_>
790+
rollingUpgradePolicy =
791+
this.RollingUpgradePolicy
792+
|> Option.map _.ArmJson
793+
|> Option.defaultValue Unchecked.defaultof<_>
752794
|}
753795

754796
type ScaleSetScaleInPolicy = {

src/Farmer/Builders/Builders.VmScaleSet.fs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,4 +650,174 @@ type VirtualMachineScaleSetBuilder() =
650650
|> Some
651651
}
652652

653+
[<CustomOperation "rolling_upgrade_enable_cross_zone_upgrade">]
654+
member _.RollingUpgradeEnableCrossZoneUpgrade(state: VmScaleSetConfig, enabled) = {
655+
state with
656+
UpgradePolicy =
657+
state.UpgradePolicy
658+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
659+
|> (fun x -> {
660+
x with
661+
RollingUpgradePolicy =
662+
x.RollingUpgradePolicy
663+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
664+
|> (fun x -> {
665+
x with
666+
EnableCrossZoneUpgrade = Some enabled
667+
})
668+
|> Some
669+
})
670+
|> Some
671+
}
672+
673+
[<CustomOperation "rolling_upgrade_max_batch_instance_percent">]
674+
member _.RollingUpgradeMaxBatchInstancePercent(state: VmScaleSetConfig, percent: int) =
675+
if percent < 5 || percent > 100 then
676+
raiseFarmer $"rolling_upgrade_max_batch_instance_percent must be between 5 and 100, but was {percent}"
677+
678+
{
679+
state with
680+
UpgradePolicy =
681+
state.UpgradePolicy
682+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
683+
|> (fun x -> {
684+
x with
685+
RollingUpgradePolicy =
686+
x.RollingUpgradePolicy
687+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
688+
|> (fun x -> {
689+
x with
690+
MaxBatchInstancePercent = Some percent
691+
})
692+
|> Some
693+
})
694+
|> Some
695+
}
696+
697+
[<CustomOperation "rolling_upgrade_max_surge">]
698+
member _.RollingUpgradeMaxSurge(state: VmScaleSetConfig, enabled) = {
699+
state with
700+
UpgradePolicy =
701+
state.UpgradePolicy
702+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
703+
|> (fun x -> {
704+
x with
705+
RollingUpgradePolicy =
706+
x.RollingUpgradePolicy
707+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
708+
|> (fun x -> { x with MaxSurge = Some enabled })
709+
|> Some
710+
})
711+
|> Some
712+
}
713+
714+
[<CustomOperation "rolling_upgrade_max_unhealthy_instance_percent">]
715+
member _.RollingUpgradeMaxUnhealthyInstancePercent(state: VmScaleSetConfig, percent: int) =
716+
if percent < 5 || percent > 100 then
717+
raiseFarmer $"rolling_upgrade_max_unhealthy_instance_percent must be between 5 and 100, but was {percent}"
718+
719+
{
720+
state with
721+
UpgradePolicy =
722+
state.UpgradePolicy
723+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
724+
|> (fun x -> {
725+
x with
726+
RollingUpgradePolicy =
727+
x.RollingUpgradePolicy
728+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
729+
|> (fun x -> {
730+
x with
731+
MaxUnhealthyInstancePercent = Some percent
732+
})
733+
|> Some
734+
})
735+
|> Some
736+
}
737+
738+
[<CustomOperation "rolling_upgrade_max_unhealthy_upgraded_instance_percent">]
739+
member _.RollingUpgradeMaxUnhealthyUpgradedInstancePercent(state: VmScaleSetConfig, percent: int) =
740+
if percent < 0 || percent > 100 then
741+
raiseFarmer
742+
$"rolling_upgrade_max_unhealthy_upgraded_instance_percent must be between 0 and 100, but was {percent}"
743+
744+
{
745+
state with
746+
UpgradePolicy =
747+
state.UpgradePolicy
748+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
749+
|> (fun x -> {
750+
x with
751+
RollingUpgradePolicy =
752+
x.RollingUpgradePolicy
753+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
754+
|> (fun x -> {
755+
x with
756+
MaxUnhealthyUpgradedInstancePercent = Some percent
757+
})
758+
|> Some
759+
})
760+
|> Some
761+
}
762+
763+
[<CustomOperation "rolling_upgrade_pause_time_between_batches">]
764+
member _.RollingUpgradePauseTimeBetweenBatches(state: VmScaleSetConfig, duration: TimeSpan) = {
765+
state with
766+
UpgradePolicy =
767+
state.UpgradePolicy
768+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
769+
|> (fun x -> {
770+
x with
771+
RollingUpgradePolicy =
772+
x.RollingUpgradePolicy
773+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
774+
|> (fun x -> {
775+
x with
776+
PauseTimeBetweenBatches = Some duration
777+
})
778+
|> Some
779+
})
780+
|> Some
781+
}
782+
783+
[<CustomOperation "rolling_upgrade_prioritize_unhealthy_instances">]
784+
member _.RollingUpgradePrioritizeUnhealthyInstances(state: VmScaleSetConfig, enabled) = {
785+
state with
786+
UpgradePolicy =
787+
state.UpgradePolicy
788+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
789+
|> (fun x -> {
790+
x with
791+
RollingUpgradePolicy =
792+
x.RollingUpgradePolicy
793+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
794+
|> (fun x -> {
795+
x with
796+
PrioritizeUnhealthyInstances = Some enabled
797+
})
798+
|> Some
799+
})
800+
|> Some
801+
}
802+
803+
[<CustomOperation "rolling_upgrade_rollback_failed_instances_on_policy_breach">]
804+
member _.RollingUpgradeRollbackFailedInstancesOnPolicyBreach(state: VmScaleSetConfig, enabled) = {
805+
state with
806+
UpgradePolicy =
807+
state.UpgradePolicy
808+
|> Option.defaultValue ScaleSetUpgradePolicy.Default
809+
|> (fun x -> {
810+
x with
811+
RollingUpgradePolicy =
812+
x.RollingUpgradePolicy
813+
|> Option.defaultValue VmssRollingUpgradePolicy.Default
814+
|> (fun x -> {
815+
x with
816+
RollbackFailedInstancesOnPolicyBreach = Some enabled
817+
})
818+
|> Some
819+
})
820+
|> Some
821+
}
822+
653823
let vmss = VirtualMachineScaleSetBuilder()

0 commit comments

Comments
 (0)