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..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 @@ -250,6 +250,28 @@ 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"), + }) +} + 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..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 @@ -28,6 +28,26 @@ 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), + ), + }, + }) +} + func TestAccOrchestratedVirtualMachineScaleSet_NonStandardCasing(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") r := OrchestratedVirtualMachineScaleSetResource{} @@ -441,6 +461,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..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 @@ -264,6 +264,28 @@ 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"), + }) +} + 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..767e1f56948a 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:** 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 ef931e6b0ae7..b0ec6d52a45f 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:** 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 ea1c14e83eaa..56f2efcd7ded 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:** Updating `zones` to remove an existing zone forces a new Virtual Machine Scale Set to be created. ---