From b6477fc05417f95a6c4ee16a1c85a1f58cddaad2 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Thu, 5 Sep 2024 13:13:27 +0800 Subject: [PATCH 1/2] support vmss zone update --- ...inux_virtual_machine_scale_set_resource.go | 31 ++++++- ...machine_scale_set_resource_scaling_test.go | 29 +++++++ ...ated_virtual_machine_scale_set_resource.go | 31 ++++++- ...l_machine_scale_set_resource_other_test.go | 80 +++++++++++++++++++ ...dows_virtual_machine_scale_set_resource.go | 32 +++++++- ...machine_scale_set_resource_scaling_test.go | 29 +++++++ ...ux_virtual_machine_scale_set.html.markdown | 4 +- ...ed_virtual_machine_scale_set.html.markdown | 4 +- ...ws_virtual_machine_scale_set.html.markdown | 4 +- 9 files changed, 238 insertions(+), 6 deletions(-) diff --git a/internal/services/compute/linux_virtual_machine_scale_set_resource.go b/internal/services/compute/linux_virtual_machine_scale_set_resource.go index 254c22c2a060..9a66e6acd2e5 100644 --- a/internal/services/compute/linux_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/linux_virtual_machine_scale_set_resource.go @@ -4,6 +4,7 @@ package compute import ( + "context" "fmt" "log" "time" @@ -58,6 +59,30 @@ func resourceLinuxVirtualMachineScaleSet() *pluginsdk.Resource { // https://github.com/Azure/azure-rest-api-specs/pull/7246 Schema: resourceLinuxVirtualMachineScaleSetSchema(), + + CustomizeDiff: pluginsdk.CustomDiffWithAll( + // Removing existing zones is currently not supported for Virtual Machine Scale Sets + pluginsdk.ForceNewIfChange("zones", func(ctx context.Context, old, new, meta interface{}) bool { + oldZones := zones.ExpandUntyped(old.(*schema.Set).List()) + newZones := zones.ExpandUntyped(new.(*schema.Set).List()) + + for _, ov := range oldZones { + found := false + for _, nv := range newZones { + if ov == nv { + found = true + break + } + } + + if !found { + return true + } + } + + return false + }), + ), } } @@ -518,6 +543,10 @@ func resourceLinuxVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, meta i } } + if d.HasChange("zones") { + update.Zones = pointer.To(zones.ExpandUntyped(d.Get("zones").(*schema.Set).List())) + } + if d.HasChange("automatic_os_upgrade_policy") || d.HasChange("rolling_upgrade_policy") { upgradePolicy := virtualmachinescalesets.UpgradePolicy{} if existing.Model.Properties.UpgradePolicy == nil { @@ -1441,7 +1470,7 @@ func resourceLinuxVirtualMachineScaleSetSchema() map[string]*pluginsdk.Schema { "termination_notification": VirtualMachineScaleSetTerminationNotificationSchema(), - "zones": commonschema.ZonesMultipleOptionalForceNew(), + "zones": commonschema.ZonesMultipleOptional(), // Computed "unique_id": { diff --git a/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go b/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go index 741a6f000a14..442c336a7313 100644 --- a/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go +++ b/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go @@ -250,6 +250,35 @@ func TestAccLinuxVirtualMachineScaleSet_scalingZonesMultiple(t *testing.T) { }) } +func TestAccLinuxVirtualMachineScaleSet_scalingZonesUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + r := LinuxVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.scalingZonesSingle(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + { + Config: r.scalingZonesMultiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + { + Config: r.scalingZonesSingle(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + }) +} + func TestAccLinuxVirtualMachineScaleSet_scalingZonesBalance(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") r := LinuxVirtualMachineScaleSetResource{} diff --git a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go index 34d2d6cf8caa..eb25fc96fa5d 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go @@ -4,6 +4,7 @@ package compute import ( + "context" "fmt" "log" "strconv" @@ -250,7 +251,7 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { "termination_notification": OrchestratedVirtualMachineScaleSetTerminationNotificationSchema(), - "zones": commonschema.ZonesMultipleOptionalForceNew(), + "zones": commonschema.ZonesMultipleOptional(), "tags": commonschema.Tags(), @@ -269,6 +270,30 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { "priority_mix": OrchestratedVirtualMachineScaleSetPriorityMixPolicySchema(), }, + + CustomizeDiff: pluginsdk.CustomDiffWithAll( + // Removing existing zones is currently not supported for Virtual Machine Scale Sets + pluginsdk.ForceNewIfChange("zones", func(ctx context.Context, old, new, meta interface{}) bool { + oldZones := zones.ExpandUntyped(old.(*schema.Set).List()) + newZones := zones.ExpandUntyped(new.(*schema.Set).List()) + + for _, ov := range oldZones { + found := false + for _, nv := range newZones { + if ov == nv { + found = true + break + } + } + + if !found { + return true + } + } + + return false + }), + ), } } @@ -1072,6 +1097,10 @@ func resourceOrchestratedVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, } } + if d.HasChange("zones") { + update.Zones = pointer.To(zones.ExpandUntyped(d.Get("zones").(*schema.Set).List())) + } + // Only two fields that can change in legacy mode if d.HasChange("proximity_placement_group_id") { if v, ok := d.GetOk("proximity_placement_group_id"); ok { diff --git a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go index e813bcefe42b..d868d6770490 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go @@ -28,6 +28,32 @@ func TestAccOrchestratedVirtualMachineScaleSet_priority(t *testing.T) { }) } +func TestAccOrchestratedVirtualMachineScaleSet_zoneUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") + r := OrchestratedVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.singleZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.multipleZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.singleZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + }) +} + func TestAccOrchestratedVirtualMachineScaleSet_NonStandardCasing(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") r := OrchestratedVirtualMachineScaleSetResource{} @@ -441,6 +467,60 @@ resource "azurerm_orchestrated_virtual_machine_scale_set" "test" { `, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) } +func (OrchestratedVirtualMachineScaleSetResource) singleZone(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +resource "azurerm_orchestrated_virtual_machine_scale_set" "test" { + name = "acctestOVMSS-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + platform_fault_domain_count = 1 + + zones = ["1"] + + tags = { + ENV = "Test" + } +} +`, data.RandomInteger, data.Locations.Primary) +} + +func (OrchestratedVirtualMachineScaleSetResource) multipleZone(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +resource "azurerm_orchestrated_virtual_machine_scale_set" "test" { + name = "acctestOVMSS-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + platform_fault_domain_count = 1 + + zones = ["1", "2"] + + tags = { + ENV = "Test" + } +} +`, data.RandomInteger, data.Locations.Primary) +} + func (OrchestratedVirtualMachineScaleSetResource) windowsHotpatchingEnabled(data acceptance.TestData) string { r := OrchestratedVirtualMachineScaleSetResource{} return fmt.Sprintf(` diff --git a/internal/services/compute/windows_virtual_machine_scale_set_resource.go b/internal/services/compute/windows_virtual_machine_scale_set_resource.go index 6df94e34e004..ed16aa9679ff 100644 --- a/internal/services/compute/windows_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/windows_virtual_machine_scale_set_resource.go @@ -4,6 +4,7 @@ package compute import ( + "context" "fmt" "log" "time" @@ -57,6 +58,30 @@ func resourceWindowsVirtualMachineScaleSet() *pluginsdk.Resource { // https://github.com/Azure/azure-rest-api-specs/pull/7246 Schema: resourceWindowsVirtualMachineScaleSetSchema(), + + CustomizeDiff: pluginsdk.CustomDiffWithAll( + // Removing existing zones is currently not supported for Virtual Machine Scale Sets + pluginsdk.ForceNewIfChange("zones", func(ctx context.Context, old, new, meta interface{}) bool { + oldZones := zones.ExpandUntyped(old.(*schema.Set).List()) + newZones := zones.ExpandUntyped(new.(*schema.Set).List()) + + for _, ov := range oldZones { + found := false + for _, nv := range newZones { + if ov == nv { + found = true + break + } + } + + if !found { + return true + } + } + + return false + }), + ), } } @@ -524,6 +549,11 @@ func resourceWindowsVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, meta automaticOSUpgradeIsEnabled = *policy.AutomaticOSUpgradePolicy.EnableAutomaticOSUpgrade } } + + if d.HasChange("zones") { + update.Zones = pointer.To(zones.ExpandUntyped(d.Get("zones").(*schema.Set).List())) + } + if d.HasChange("automatic_os_upgrade_policy") || d.HasChange("rolling_upgrade_policy") { upgradePolicy := virtualmachinescalesets.UpgradePolicy{} if existing.Model.Properties.UpgradePolicy == nil { @@ -1498,7 +1528,7 @@ func resourceWindowsVirtualMachineScaleSetSchema() map[string]*pluginsdk.Schema "termination_notification": VirtualMachineScaleSetTerminationNotificationSchema(), - "zones": commonschema.ZonesMultipleOptionalForceNew(), + "zones": commonschema.ZonesMultipleOptional(), "unique_id": { Type: pluginsdk.TypeString, diff --git a/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go b/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go index 9ef3a0414b8f..13842434f347 100644 --- a/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go +++ b/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go @@ -264,6 +264,35 @@ func TestAccWindowsVirtualMachineScaleSet_scalingZonesMultiple(t *testing.T) { }) } +func TestAccWindowsVirtualMachineScaleSet_scalingZonesUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + r := WindowsVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.scalingZonesSingle(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + { + Config: r.scalingZonesMultiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + { + Config: r.scalingZonesSingle(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password"), + }) +} + func TestAccWindowsVirtualMachineScaleSet_scalingZonesBalance(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") r := WindowsVirtualMachineScaleSetResource{} diff --git a/website/docs/r/linux_virtual_machine_scale_set.html.markdown b/website/docs/r/linux_virtual_machine_scale_set.html.markdown index 096a2239d2f9..a4d26f89ca3b 100644 --- a/website/docs/r/linux_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/linux_virtual_machine_scale_set.html.markdown @@ -232,7 +232,9 @@ resource "azurerm_linux_virtual_machine_scale_set" "example" { -> **Note:** This can only be set to `true` when one or more `zones` are configured. -* `zones` - (Optional) Specifies a list of Availability Zones in which this Linux Virtual Machine Scale Set should be located. Changing this forces a new Linux Virtual Machine Scale Set to be created. +* `zones` - (Optional) Specifies a list of Availability Zones in which this Linux Virtual Machine Scale Set should be located. + +-> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. --- diff --git a/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown b/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown index ef931e6b0ae7..5d55c10f035b 100644 --- a/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown @@ -113,7 +113,9 @@ resource "azurerm_orchestrated_virtual_machine_scale_set" "example" { -> **Note:** This can only be set to `true` when one or more `zones` are configured. -* `zones` - (Optional) Specifies a list of Availability Zones across which the Virtual Machine Scale Set will create instances. Changing this forces a new Virtual Machine Scale Set to be created. +* `zones` - (Optional) Specifies a list of Availability Zones across which the Virtual Machine Scale Set will create instances. + +-> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. -> **Note:** Availability Zones are [only supported in several regions at this time](https://docs.microsoft.com/azure/availability-zones/az-overview). diff --git a/website/docs/r/windows_virtual_machine_scale_set.html.markdown b/website/docs/r/windows_virtual_machine_scale_set.html.markdown index ea1c14e83eaa..3ac16cec0343 100644 --- a/website/docs/r/windows_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/windows_virtual_machine_scale_set.html.markdown @@ -223,7 +223,9 @@ resource "azurerm_windows_virtual_machine_scale_set" "example" { -> **Note:** This can only be set to `true` when one or more `zones` are configured. -* `zones` - (Optional) Specifies a list of Availability Zones in which this Windows Virtual Machine Scale Set should be located. Changing this forces a new Windows Virtual Machine Scale Set to be created. +* `zones` - (Optional) Specifies a list of Availability Zones in which this Windows Virtual Machine Scale Set should be located. + +-> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. --- From 14995ce6f9fa77bea486c3896fe93150f63bb1fd Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 9 Sep 2024 10:19:18 +0800 Subject: [PATCH 2/2] resolve comments --- ...inux_virtual_machine_scale_set_resource_scaling_test.go | 7 ------- ...trated_virtual_machine_scale_set_resource_other_test.go | 6 ------ ...dows_virtual_machine_scale_set_resource_scaling_test.go | 7 ------- .../docs/r/linux_virtual_machine_scale_set.html.markdown | 2 +- .../r/orchestrated_virtual_machine_scale_set.html.markdown | 2 +- .../docs/r/windows_virtual_machine_scale_set.html.markdown | 2 +- 6 files changed, 3 insertions(+), 23 deletions(-) diff --git a/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go b/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go index 442c336a7313..bf804433f441 100644 --- a/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go +++ b/internal/services/compute/linux_virtual_machine_scale_set_resource_scaling_test.go @@ -269,13 +269,6 @@ func TestAccLinuxVirtualMachineScaleSet_scalingZonesUpdate(t *testing.T) { ), }, data.ImportStep("admin_password"), - { - Config: r.scalingZonesSingle(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep("admin_password"), }) } diff --git a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go index d868d6770490..3e2bf4be613d 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource_other_test.go @@ -45,12 +45,6 @@ func TestAccOrchestratedVirtualMachineScaleSet_zoneUpdate(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), ), }, - { - Config: r.singleZone(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, }) } diff --git a/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go b/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go index 13842434f347..3577f554d801 100644 --- a/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go +++ b/internal/services/compute/windows_virtual_machine_scale_set_resource_scaling_test.go @@ -283,13 +283,6 @@ func TestAccWindowsVirtualMachineScaleSet_scalingZonesUpdate(t *testing.T) { ), }, data.ImportStep("admin_password"), - { - Config: r.scalingZonesSingle(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep("admin_password"), }) } diff --git a/website/docs/r/linux_virtual_machine_scale_set.html.markdown b/website/docs/r/linux_virtual_machine_scale_set.html.markdown index a4d26f89ca3b..767e1f56948a 100644 --- a/website/docs/r/linux_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/linux_virtual_machine_scale_set.html.markdown @@ -234,7 +234,7 @@ resource "azurerm_linux_virtual_machine_scale_set" "example" { * `zones` - (Optional) Specifies a list of Availability Zones in which this Linux Virtual Machine Scale Set should be located. --> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. +-> **Note:** Updating `zones` to remove an existing zone forces a new Virtual Machine Scale Set to be created. --- diff --git a/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown b/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown index 5d55c10f035b..b0ec6d52a45f 100644 --- a/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown @@ -115,7 +115,7 @@ resource "azurerm_orchestrated_virtual_machine_scale_set" "example" { * `zones` - (Optional) Specifies a list of Availability Zones across which the Virtual Machine Scale Set will create instances. --> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. +-> **Note:** Updating `zones` to remove an existing zone forces a new Virtual Machine Scale Set to be created. -> **Note:** Availability Zones are [only supported in several regions at this time](https://docs.microsoft.com/azure/availability-zones/az-overview). diff --git a/website/docs/r/windows_virtual_machine_scale_set.html.markdown b/website/docs/r/windows_virtual_machine_scale_set.html.markdown index 3ac16cec0343..56f2efcd7ded 100644 --- a/website/docs/r/windows_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/windows_virtual_machine_scale_set.html.markdown @@ -225,7 +225,7 @@ resource "azurerm_windows_virtual_machine_scale_set" "example" { * `zones` - (Optional) Specifies a list of Availability Zones in which this Windows Virtual Machine Scale Set should be located. --> **Note:** Removing existing zones from existing Virtual Machine Scale Set is currently not supported. +-> **Note:** Updating `zones` to remove an existing zone forces a new Virtual Machine Scale Set to be created. ---