diff --git a/internal/services/compute/linux_virtual_machine_scale_set_other_resource_test.go b/internal/services/compute/linux_virtual_machine_scale_set_other_resource_test.go index ccfba501beb5..1e5bec195454 100644 --- a/internal/services/compute/linux_virtual_machine_scale_set_other_resource_test.go +++ b/internal/services/compute/linux_virtual_machine_scale_set_other_resource_test.go @@ -414,32 +414,51 @@ func TestAccLinuxVirtualMachineScaleSet_otherScaleInPolicy(t *testing.T) { }) } -func TestAccLinuxVirtualMachineScaleSet_otherTerminateNotification(t *testing.T) { +func TestAccLinuxVirtualMachineScaleSet_otherTerminationNotification(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") r := LinuxVirtualMachineScaleSetResource{} data.ResourceTest(t, r, []acceptance.TestStep{ - // turn terminate notification on + // turn termination notification on { - Config: r.otherTerminateNotification(data, true), + Config: r.otherTerminationNotification(data, true), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"), - check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("true"), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), ), }, data.ImportStep("admin_password"), - // turn terminate notification off + // turn termination notification off { - Config: r.otherTerminateNotification(data, false), + Config: r.otherTerminationNotification(data, false), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"), - check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("false"), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("false"), ), }, data.ImportStep("admin_password"), - // turn terminate notification on again + // turn termination notification on again + { + Config: r.otherTerminationNotification(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), + ), + }, + data.ImportStep("admin_password"), + }) +} + +// TODO remove TestAccLinuxVirtualMachineScaleSet_otherTerminationNotificationMigration in 4.0 +func TestAccLinuxVirtualMachineScaleSet_otherTerminationNotificationMigration(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + r := LinuxVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + // old: terminate_notification { Config: r.otherTerminateNotification(data, true), Check: acceptance.ComposeTestCheckFunc( @@ -449,6 +468,16 @@ func TestAccLinuxVirtualMachineScaleSet_otherTerminateNotification(t *testing.T) ), }, data.ImportStep("admin_password"), + // new: termination_notification + { + Config: r.otherTerminationNotification(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), + ), + }, + data.ImportStep("admin_password"), }) } @@ -1907,6 +1936,7 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { `, r.template(data), data.RandomInteger) } +// TODO remove otherTerminateNotification in 4.0 func (r LinuxVirtualMachineScaleSetResource) otherTerminateNotification(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %s @@ -1953,6 +1983,52 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { `, r.template(data), data.RandomInteger, enabled) } +func (r LinuxVirtualMachineScaleSetResource) otherTerminationNotification(data acceptance.TestData, enabled bool) string { + return fmt.Sprintf(` +%s + +resource "azurerm_linux_virtual_machine_scale_set" "test" { + name = "acctestvmss-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + os_disk { + disk_size_gb = 30 + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + termination_notification { + enabled = %t + } +} +`, r.template(data), data.RandomInteger, enabled) +} + func (r LinuxVirtualMachineScaleSetResource) otherAutomaticRepairsPolicy(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %[1]s @@ -2103,7 +2179,7 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { } } - terminate_notification { + termination_notification { enabled = %t } } 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 668349812817..e0a241095a3c 100644 --- a/internal/services/compute/linux_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/linux_virtual_machine_scale_set_resource.go @@ -48,260 +48,7 @@ func resourceLinuxVirtualMachineScaleSet() *pluginsdk.Resource { // TODO: exposing requireGuestProvisionSignal once it's available // https://github.com/Azure/azure-rest-api-specs/pull/7246 - Schema: map[string]*pluginsdk.Schema{ - "name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validate.VirtualMachineName, - }, - - "resource_group_name": azure.SchemaResourceGroupName(), - - "location": azure.SchemaLocation(), - - // Required - "admin_username": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "network_interface": VirtualMachineScaleSetNetworkInterfaceSchema(), - - "os_disk": VirtualMachineScaleSetOSDiskSchema(), - - "instances": { - Type: pluginsdk.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(0), - }, - - "sku": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - // Optional - "additional_capabilities": VirtualMachineScaleSetAdditionalCapabilitiesSchema(), - - "admin_password": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - Sensitive: true, - DiffSuppressFunc: adminPasswordDiffSuppressFunc, - }, - - "admin_ssh_key": SSHKeysSchema(false), - - "automatic_os_upgrade_policy": VirtualMachineScaleSetAutomatedOSUpgradePolicySchema(), - - "automatic_instance_repair": VirtualMachineScaleSetAutomaticRepairsPolicySchema(), - - "boot_diagnostics": bootDiagnosticsSchema(), - - "computer_name_prefix": { - Type: pluginsdk.TypeString, - Optional: true, - - // Computed since we reuse the VM name if one's not specified - Computed: true, - ForceNew: true, - - ValidateFunc: validate.LinuxComputerNamePrefix, - }, - - "custom_data": base64.OptionalSchema(false), - - "data_disk": VirtualMachineScaleSetDataDiskSchema(), - - "disable_password_authentication": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "do_not_run_extensions_on_overprovisioned_machines": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: false, - }, - - "edge_zone": commonschema.EdgeZoneOptionalForceNew(), - - "encryption_at_host_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - }, - - "eviction_policy": { - // only applicable when `priority` is set to `Spot` - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachineEvictionPolicyTypesDeallocate), - string(compute.VirtualMachineEvictionPolicyTypesDelete), - }, false), - }, - - "extension": VirtualMachineScaleSetExtensionsSchema(), - - "extensions_time_budget": { - Type: pluginsdk.TypeString, - Optional: true, - Default: "PT1H30M", - ValidateFunc: azValidate.ISO8601DurationBetween("PT15M", "PT2H"), - }, - - "health_probe_id": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: azure.ValidateResourceID, - }, - - "identity": commonschema.SystemAssignedUserAssignedIdentityOptional(), - - "max_bid_price": { - Type: pluginsdk.TypeFloat, - Optional: true, - Default: -1, - ValidateFunc: validate.SpotMaxPrice, - }, - - "overprovision": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "plan": planSchema(), - - "platform_fault_domain_count": { - Type: pluginsdk.TypeInt, - Optional: true, - ForceNew: true, - Computed: true, - }, - - "priority": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - Default: string(compute.VirtualMachinePriorityTypesRegular), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachinePriorityTypesRegular), - string(compute.VirtualMachinePriorityTypesSpot), - }, false), - }, - - "provision_vm_agent": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - ForceNew: true, - }, - - "proximity_placement_group_id": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validate.ProximityPlacementGroupID, - // the Compute API is broken and returns the Resource Group name in UPPERCASE :shrug:, github issue: https://github.com/Azure/azure-rest-api-specs/issues/10016 - DiffSuppressFunc: suppress.CaseDifference, - }, - - "rolling_upgrade_policy": VirtualMachineScaleSetRollingUpgradePolicySchema(), - - "secret": linuxSecretSchema(), - - "secure_boot_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - }, - - "single_placement_group": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "source_image_id": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.Any( - validate.ImageID, - validate.SharedImageID, - validate.SharedImageVersionID, - ), - }, - - "source_image_reference": sourceImageReferenceSchema(false), - - "tags": tags.Schema(), - - "upgrade_mode": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - Default: string(compute.UpgradeModeManual), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.UpgradeModeAutomatic), - string(compute.UpgradeModeManual), - string(compute.UpgradeModeRolling), - }, false), - }, - - "user_data": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsBase64, - }, - - "vtpm_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - }, - - "zone_balance": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - Default: false, - }, - - "scale_in_policy": { - Type: pluginsdk.TypeString, - Optional: true, - Default: string(compute.VirtualMachineScaleSetScaleInRulesDefault), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachineScaleSetScaleInRulesDefault), - string(compute.VirtualMachineScaleSetScaleInRulesNewestVM), - string(compute.VirtualMachineScaleSetScaleInRulesOldestVM), - }, false), - }, - - "terminate_notification": VirtualMachineScaleSetTerminateNotificationSchema(), - - "zones": func() *schema.Schema { - if !features.ThreePointOhBeta() { - return azure.SchemaZones() - } - - return commonschema.ZonesMultipleOptionalForceNew() - }(), - - // Computed - "unique_id": { - Type: pluginsdk.TypeString, - Computed: true, - }, - }, + Schema: resourceLinuxVirtualMachineScaleSetSchema(), } } @@ -527,7 +274,13 @@ func resourceLinuxVirtualMachineScaleSetCreate(d *pluginsdk.ResourceData, meta i return fmt.Errorf("an `eviction_policy` must be specified when `priority` is set to `Spot`") } - if v, ok := d.GetOk("terminate_notification"); ok { + if !features.FourPointOhBeta() { + if v, ok := d.GetOk("terminate_notification"); ok { + virtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(v.([]interface{})) + } + } + + if v, ok := d.GetOk("termination_notification"); ok { virtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(v.([]interface{})) } @@ -834,8 +587,15 @@ func resourceLinuxVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, meta i } } - if d.HasChange("terminate_notification") { - notificationRaw := d.Get("terminate_notification").([]interface{}) + if !features.FourPointOhBeta() { + if d.HasChange("terminate_notification") { + notificationRaw := d.Get("terminate_notification").([]interface{}) + updateProps.VirtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(notificationRaw) + } + } + + if d.HasChange("termination_notification") { + notificationRaw := d.Get("termination_notification").([]interface{}) updateProps.VirtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(notificationRaw) } @@ -1084,9 +844,17 @@ func resourceLinuxVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, meta int d.Set("health_probe_id", healthProbeId) } + if !features.FourPointOhBeta() { + if scheduleProfile := profile.ScheduledEventsProfile; scheduleProfile != nil { + if err := d.Set("terminate_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { + return fmt.Errorf("setting `terminate_notification`: %+v", err) + } + } + } + if scheduleProfile := profile.ScheduledEventsProfile; scheduleProfile != nil { - if err := d.Set("terminate_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { - return fmt.Errorf("setting `terminate_notification`: %+v", err) + if err := d.Set("termination_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { + return fmt.Errorf("setting `termination_notification`: %+v", err) } } @@ -1210,3 +978,267 @@ func resourceLinuxVirtualMachineScaleSetDelete(d *pluginsdk.ResourceData, meta i return nil } + +func resourceLinuxVirtualMachineScaleSetSchema() map[string]*pluginsdk.Schema { + out := map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.VirtualMachineName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + // Required + "admin_username": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "network_interface": VirtualMachineScaleSetNetworkInterfaceSchema(), + + "os_disk": VirtualMachineScaleSetOSDiskSchema(), + + "instances": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(0), + }, + + "sku": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + // Optional + "additional_capabilities": VirtualMachineScaleSetAdditionalCapabilitiesSchema(), + + "admin_password": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Sensitive: true, + DiffSuppressFunc: adminPasswordDiffSuppressFunc, + }, + + "admin_ssh_key": SSHKeysSchema(false), + + "automatic_os_upgrade_policy": VirtualMachineScaleSetAutomatedOSUpgradePolicySchema(), + + "automatic_instance_repair": VirtualMachineScaleSetAutomaticRepairsPolicySchema(), + + "boot_diagnostics": bootDiagnosticsSchema(), + + "computer_name_prefix": { + Type: pluginsdk.TypeString, + Optional: true, + + // Computed since we reuse the VM name if one's not specified + Computed: true, + ForceNew: true, + + ValidateFunc: validate.LinuxComputerNamePrefix, + }, + + "custom_data": base64.OptionalSchema(false), + + "data_disk": VirtualMachineScaleSetDataDiskSchema(), + + "disable_password_authentication": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "do_not_run_extensions_on_overprovisioned_machines": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "edge_zone": commonschema.EdgeZoneOptionalForceNew(), + + "encryption_at_host_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "eviction_policy": { + // only applicable when `priority` is set to `Spot` + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachineEvictionPolicyTypesDeallocate), + string(compute.VirtualMachineEvictionPolicyTypesDelete), + }, false), + }, + + "extension": VirtualMachineScaleSetExtensionsSchema(), + + "extensions_time_budget": { + Type: pluginsdk.TypeString, + Optional: true, + Default: "PT1H30M", + ValidateFunc: azValidate.ISO8601DurationBetween("PT15M", "PT2H"), + }, + + "health_probe_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "identity": commonschema.SystemAssignedUserAssignedIdentityOptional(), + + "max_bid_price": { + Type: pluginsdk.TypeFloat, + Optional: true, + Default: -1, + ValidateFunc: validate.SpotMaxPrice, + }, + + "overprovision": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "plan": planSchema(), + + "platform_fault_domain_count": { + Type: pluginsdk.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "priority": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(compute.VirtualMachinePriorityTypesRegular), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachinePriorityTypesRegular), + string(compute.VirtualMachinePriorityTypesSpot), + }, false), + }, + + "provision_vm_agent": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + ForceNew: true, + }, + + "proximity_placement_group_id": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validate.ProximityPlacementGroupID, + // the Compute API is broken and returns the Resource Group name in UPPERCASE :shrug:, github issue: https://github.com/Azure/azure-rest-api-specs/issues/10016 + DiffSuppressFunc: suppress.CaseDifference, + }, + + "rolling_upgrade_policy": VirtualMachineScaleSetRollingUpgradePolicySchema(), + + "secret": linuxSecretSchema(), + + "secure_boot_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + }, + + "single_placement_group": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "source_image_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.Any( + validate.ImageID, + validate.SharedImageID, + validate.SharedImageVersionID, + ), + }, + + "source_image_reference": sourceImageReferenceSchema(false), + + "tags": tags.Schema(), + + "upgrade_mode": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(compute.UpgradeModeManual), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.UpgradeModeAutomatic), + string(compute.UpgradeModeManual), + string(compute.UpgradeModeRolling), + }, false), + }, + + "user_data": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsBase64, + }, + + "vtpm_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + }, + + "zone_balance": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + Default: false, + }, + + "scale_in_policy": { + Type: pluginsdk.TypeString, + Optional: true, + Default: string(compute.VirtualMachineScaleSetScaleInRulesDefault), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachineScaleSetScaleInRulesDefault), + string(compute.VirtualMachineScaleSetScaleInRulesNewestVM), + string(compute.VirtualMachineScaleSetScaleInRulesOldestVM), + }, false), + }, + + "termination_notification": VirtualMachineScaleSetTerminationNotificationSchema(), + + "zones": func() *schema.Schema { + if !features.ThreePointOhBeta() { + return azure.SchemaZones() + } + + return commonschema.ZonesMultipleOptionalForceNew() + }(), + + // Computed + "unique_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + } + + if !features.FourPointOhBeta() { + out["terminate_notification"] = VirtualMachineScaleSetTerminateNotificationSchema() + + } + + return out +} diff --git a/internal/services/compute/orchestrated_virtual_machine_scale_set.go b/internal/services/compute/orchestrated_virtual_machine_scale_set.go index 01cae30580dc..a9d97ba9c3a9 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set.go @@ -611,7 +611,7 @@ func OrchestratedVirtualMachineScaleSetOSDiskSchema() *pluginsdk.Schema { } } -func OrchestratedVirtualMachineScaleSetTerminateNotificationSchema() *pluginsdk.Schema { +func OrchestratedVirtualMachineScaleSetTerminationNotificationSchema() *pluginsdk.Schema { return &pluginsdk.Schema{ Type: pluginsdk.TypeList, Optional: true, 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 7fcdb9288de2..e0d4950c59c9 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go @@ -192,7 +192,7 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { Default: false, }, - "termination_notification": OrchestratedVirtualMachineScaleSetTerminateNotificationSchema(), + "termination_notification": OrchestratedVirtualMachineScaleSetTerminationNotificationSchema(), "zones": func() *schema.Schema { if !features.ThreePointOhBeta() { diff --git a/internal/services/compute/virtual_machine_scale_set.go b/internal/services/compute/virtual_machine_scale_set.go index 1c3bcdd139c0..57856231f612 100644 --- a/internal/services/compute/virtual_machine_scale_set.go +++ b/internal/services/compute/virtual_machine_scale_set.go @@ -1398,7 +1398,33 @@ func FlattenVirtualMachineScaleSetRollingUpgradePolicy(input *compute.RollingUpg } } +// TODO remove VirtualMachineScaleSetTerminateNotificationSchema in 4.0 func VirtualMachineScaleSetTerminateNotificationSchema() *pluginsdk.Schema { + return &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Deprecated: "`terminate_notification` has been renamed to `termination_notification` and will be removed in 4.0.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "enabled": { + Type: pluginsdk.TypeBool, + Required: true, + }, + "timeout": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: azValidate.ISO8601Duration, + Default: "PT5M", + }, + }, + }, + ConflictsWith: []string{"termination_notification"}, + } +} + +func VirtualMachineScaleSetTerminationNotificationSchema() *pluginsdk.Schema { return &pluginsdk.Schema{ Type: pluginsdk.TypeList, Optional: true, @@ -1418,6 +1444,8 @@ func VirtualMachineScaleSetTerminateNotificationSchema() *pluginsdk.Schema { }, }, }, + // TODO remove ConflictsWith in 4.0 + ConflictsWith: []string{"terminate_notification"}, } } diff --git a/internal/services/compute/windows_virtual_machine_scale_set_other_resource_test.go b/internal/services/compute/windows_virtual_machine_scale_set_other_resource_test.go index 37b95e413906..d3dc96124336 100644 --- a/internal/services/compute/windows_virtual_machine_scale_set_other_resource_test.go +++ b/internal/services/compute/windows_virtual_machine_scale_set_other_resource_test.go @@ -533,32 +533,51 @@ func TestAccWindowsVirtualMachineScaleSet_otherScaleInPolicy(t *testing.T) { }) } -func TestAccWindowsVirtualMachineScaleSet_otherTerminateNotification(t *testing.T) { +func TestAccWindowsVirtualMachineScaleSet_otherTerminationNotification(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") r := WindowsVirtualMachineScaleSetResource{} data.ResourceTest(t, r, []acceptance.TestStep{ - // turn terminate notification on + // turn termination notification on { - Config: r.otherTerminateNotification(data, true), + Config: r.otherTerminationNotification(data, true), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"), - check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("true"), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), ), }, data.ImportStep("admin_password"), - // turn terminate notification off + // turn termination notification off { - Config: r.otherTerminateNotification(data, false), + Config: r.otherTerminationNotification(data, false), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("terminate_notification.#").HasValue("1"), - check.That(data.ResourceName).Key("terminate_notification.0.enabled").HasValue("false"), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("false"), ), }, data.ImportStep("admin_password"), - // turn terminate notification on again + // turn termination notification on again + { + Config: r.otherTerminationNotification(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), + ), + }, + data.ImportStep("admin_password"), + }) +} + +// TODO remove TestAccWindowsVirtualMachineScaleSet_otherTerminationNotificationMigration in 4.0 +func TestAccWindowsVirtualMachineScaleSet_otherTerminationNotificationMigration(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + r := WindowsVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + // old: terminate_notification { Config: r.otherTerminateNotification(data, true), Check: acceptance.ComposeTestCheckFunc( @@ -568,6 +587,16 @@ func TestAccWindowsVirtualMachineScaleSet_otherTerminateNotification(t *testing. ), }, data.ImportStep("admin_password"), + // new: termination_notification + { + Config: r.otherTerminationNotification(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("termination_notification.#").HasValue("1"), + check.That(data.ResourceName).Key("termination_notification.0.enabled").HasValue("true"), + ), + }, + data.ImportStep("admin_password"), }) } @@ -2342,6 +2371,7 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { `, r.template(data)) } +// TODO remove otherTerminateNotification in 4.0 func (r WindowsVirtualMachineScaleSetResource) otherTerminateNotification(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %s @@ -2385,6 +2415,49 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { `, r.template(data), enabled) } +func (r WindowsVirtualMachineScaleSetResource) otherTerminationNotification(data acceptance.TestData, enabled bool) string { + return fmt.Sprintf(` +%s + +resource "azurerm_windows_virtual_machine_scale_set" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + termination_notification { + enabled = %t + } +} +`, r.template(data), enabled) +} + func (r WindowsVirtualMachineScaleSetResource) otherAutomaticRepairsPolicy(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %[1]s @@ -2531,7 +2604,7 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { } } - terminate_notification { + termination_notification { enabled = %t } } 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 77daf4034dc6..bbb8b0f502c8 100644 --- a/internal/services/compute/windows_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/windows_virtual_machine_scale_set_resource.go @@ -51,283 +51,7 @@ func resourceWindowsVirtualMachineScaleSet() *pluginsdk.Resource { // TODO: exposing requireGuestProvisionSignal once it's available // https://github.com/Azure/azure-rest-api-specs/pull/7246 - Schema: map[string]*pluginsdk.Schema{ - "name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: computeValidate.VirtualMachineName, - }, - - "resource_group_name": azure.SchemaResourceGroupName(), - - "location": azure.SchemaLocation(), - - // Required - "admin_username": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "admin_password": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - Sensitive: true, - DiffSuppressFunc: adminPasswordDiffSuppressFunc, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "network_interface": VirtualMachineScaleSetNetworkInterfaceSchema(), - - "os_disk": VirtualMachineScaleSetOSDiskSchema(), - - "instances": { - Type: pluginsdk.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(0), - }, - - "sku": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - // Optional - "additional_capabilities": VirtualMachineScaleSetAdditionalCapabilitiesSchema(), - - "additional_unattend_content": additionalUnattendContentSchema(), - - "automatic_os_upgrade_policy": VirtualMachineScaleSetAutomatedOSUpgradePolicySchema(), - - "automatic_instance_repair": VirtualMachineScaleSetAutomaticRepairsPolicySchema(), - - "boot_diagnostics": bootDiagnosticsSchema(), - - "computer_name_prefix": { - Type: pluginsdk.TypeString, - Optional: true, - - // Computed since we reuse the VM name if one's not specified - Computed: true, - ForceNew: true, - - ValidateFunc: computeValidate.WindowsComputerNamePrefix, - }, - - "custom_data": base64.OptionalSchema(false), - - "data_disk": VirtualMachineScaleSetDataDiskSchema(), - - "do_not_run_extensions_on_overprovisioned_machines": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: false, - }, - - "edge_zone": commonschema.EdgeZoneOptionalForceNew(), - - // TODO 4.0: change this from enable_* to *_enabled - "enable_automatic_updates": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "encryption_at_host_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - }, - - "eviction_policy": { - // only applicable when `priority` is set to `Spot` - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachineEvictionPolicyTypesDeallocate), - string(compute.VirtualMachineEvictionPolicyTypesDelete), - }, false), - }, - - "extension": VirtualMachineScaleSetExtensionsSchema(), - - "extensions_time_budget": { - Type: pluginsdk.TypeString, - Optional: true, - Default: "PT1H30M", - ValidateFunc: validate.ISO8601DurationBetween("PT15M", "PT2H"), - }, - - "health_probe_id": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: azure.ValidateResourceID, - }, - - "identity": commonschema.SystemAssignedUserAssignedIdentityOptional(), - - "license_type": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "None", - "Windows_Client", - "Windows_Server", - }, false), - DiffSuppressFunc: func(_, old, new string, _ *pluginsdk.ResourceData) bool { - if old == "None" && new == "" || old == "" && new == "None" { - return true - } - - return false - }, - }, - - "max_bid_price": { - Type: pluginsdk.TypeFloat, - Optional: true, - Default: -1, - ValidateFunc: computeValidate.SpotMaxPrice, - }, - - "overprovision": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "plan": planSchema(), - - "platform_fault_domain_count": { - Type: pluginsdk.TypeInt, - Optional: true, - ForceNew: true, - Computed: true, - }, - - "priority": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - Default: string(compute.VirtualMachinePriorityTypesRegular), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachinePriorityTypesRegular), - string(compute.VirtualMachinePriorityTypesSpot), - }, false), - }, - - "provision_vm_agent": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - ForceNew: true, - }, - - "proximity_placement_group_id": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: azure.ValidateResourceID, - // the Compute API is broken and returns the Resource Group name in UPPERCASE :shrug:, github issue: https://github.com/Azure/azure-rest-api-specs/issues/10016 - DiffSuppressFunc: suppress.CaseDifference, - }, - - "rolling_upgrade_policy": VirtualMachineScaleSetRollingUpgradePolicySchema(), - - "secret": windowsSecretSchema(), - - "secure_boot_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - }, - - "single_placement_group": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - }, - - "source_image_id": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: azure.ValidateResourceID, - }, - - "source_image_reference": sourceImageReferenceSchema(false), - - "tags": tags.Schema(), - - "timezone": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: computeValidate.VirtualMachineTimeZone(), - }, - - "upgrade_mode": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - Default: string(compute.UpgradeModeManual), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.UpgradeModeAutomatic), - string(compute.UpgradeModeManual), - string(compute.UpgradeModeRolling), - }, false), - }, - - "user_data": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsBase64, - }, - - "vtpm_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - }, - - "winrm_listener": winRmListenerSchema(), - - "zone_balance": { - Type: pluginsdk.TypeBool, - Optional: true, - ForceNew: true, - Default: false, - }, - - "scale_in_policy": { - Type: pluginsdk.TypeString, - Optional: true, - Default: string(compute.VirtualMachineScaleSetScaleInRulesDefault), - ValidateFunc: validation.StringInSlice([]string{ - string(compute.VirtualMachineScaleSetScaleInRulesDefault), - string(compute.VirtualMachineScaleSetScaleInRulesNewestVM), - string(compute.VirtualMachineScaleSetScaleInRulesOldestVM), - }, false), - }, - - "terminate_notification": VirtualMachineScaleSetTerminateNotificationSchema(), - - "zones": func() *schema.Schema { - if !features.ThreePointOhBeta() { - return azure.SchemaZones() - } - - return commonschema.ZonesMultipleOptionalForceNew() - }(), - - // Computed - "unique_id": { - Type: pluginsdk.TypeString, - Computed: true, - }, - }, + Schema: resourceWindowsVirtualMachineScaleSetSchema(), } } @@ -563,7 +287,13 @@ func resourceWindowsVirtualMachineScaleSetCreate(d *pluginsdk.ResourceData, meta virtualMachineProfile.OsProfile.WindowsConfiguration.TimeZone = utils.String(v.(string)) } - if v, ok := d.GetOk("terminate_notification"); ok { + if !features.FourPointOhBeta() { + if v, ok := d.GetOk("terminate_notification"); ok { + virtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(v.([]interface{})) + } + } + + if v, ok := d.GetOk("termination_notification"); ok { virtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(v.([]interface{})) } @@ -873,8 +603,15 @@ func resourceWindowsVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, meta } } - if d.HasChange("terminate_notification") { - notificationRaw := d.Get("terminate_notification").([]interface{}) + if !features.FourPointOhBeta() { + if d.HasChange("terminate_notification") { + notificationRaw := d.Get("terminate_notification").([]interface{}) + updateProps.VirtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(notificationRaw) + } + } + + if d.HasChange("termination_notification") { + notificationRaw := d.Get("termination_notification").([]interface{}) updateProps.VirtualMachineProfile.ScheduledEventsProfile = ExpandVirtualMachineScaleSetScheduledEventsProfile(notificationRaw) } @@ -1164,9 +901,17 @@ func resourceWindowsVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, meta i d.Set("health_probe_id", healthProbeId) } + if !features.FourPointOhBeta() { + if scheduleProfile := profile.ScheduledEventsProfile; scheduleProfile != nil { + if err := d.Set("terminate_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { + return fmt.Errorf("setting `terminate_notification`: %+v", err) + } + } + } + if scheduleProfile := profile.ScheduledEventsProfile; scheduleProfile != nil { - if err := d.Set("terminate_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { - return fmt.Errorf("setting `terminate_notification`: %+v", err) + if err := d.Set("termination_notification", FlattenVirtualMachineScaleSetScheduledEventsProfile(scheduleProfile)); err != nil { + return fmt.Errorf("setting `termination_notification`: %+v", err) } } @@ -1275,3 +1020,289 @@ func resourceWindowsVirtualMachineScaleSetDelete(d *pluginsdk.ResourceData, meta return nil } + +func resourceWindowsVirtualMachineScaleSetSchema() map[string]*pluginsdk.Schema { + out := map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: computeValidate.VirtualMachineName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + // Required + "admin_username": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "admin_password": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + DiffSuppressFunc: adminPasswordDiffSuppressFunc, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "network_interface": VirtualMachineScaleSetNetworkInterfaceSchema(), + + "os_disk": VirtualMachineScaleSetOSDiskSchema(), + + "instances": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(0), + }, + + "sku": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + // Optional + "additional_capabilities": VirtualMachineScaleSetAdditionalCapabilitiesSchema(), + + "additional_unattend_content": additionalUnattendContentSchema(), + + "automatic_os_upgrade_policy": VirtualMachineScaleSetAutomatedOSUpgradePolicySchema(), + + "automatic_instance_repair": VirtualMachineScaleSetAutomaticRepairsPolicySchema(), + + "boot_diagnostics": bootDiagnosticsSchema(), + + "computer_name_prefix": { + Type: pluginsdk.TypeString, + Optional: true, + + // Computed since we reuse the VM name if one's not specified + Computed: true, + ForceNew: true, + + ValidateFunc: computeValidate.WindowsComputerNamePrefix, + }, + + "custom_data": base64.OptionalSchema(false), + + "data_disk": VirtualMachineScaleSetDataDiskSchema(), + + "do_not_run_extensions_on_overprovisioned_machines": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "edge_zone": commonschema.EdgeZoneOptionalForceNew(), + + // TODO 4.0: change this from enable_* to *_enabled + "enable_automatic_updates": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "encryption_at_host_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "eviction_policy": { + // only applicable when `priority` is set to `Spot` + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachineEvictionPolicyTypesDeallocate), + string(compute.VirtualMachineEvictionPolicyTypesDelete), + }, false), + }, + + "extension": VirtualMachineScaleSetExtensionsSchema(), + + "extensions_time_budget": { + Type: pluginsdk.TypeString, + Optional: true, + Default: "PT1H30M", + ValidateFunc: validate.ISO8601DurationBetween("PT15M", "PT2H"), + }, + + "health_probe_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "identity": commonschema.SystemAssignedUserAssignedIdentityOptional(), + + "license_type": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "None", + "Windows_Client", + "Windows_Server", + }, false), + DiffSuppressFunc: func(_, old, new string, _ *pluginsdk.ResourceData) bool { + if old == "None" && new == "" || old == "" && new == "None" { + return true + } + + return false + }, + }, + + "max_bid_price": { + Type: pluginsdk.TypeFloat, + Optional: true, + Default: -1, + ValidateFunc: computeValidate.SpotMaxPrice, + }, + + "overprovision": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "plan": planSchema(), + + "platform_fault_domain_count": { + Type: pluginsdk.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + }, + + "priority": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(compute.VirtualMachinePriorityTypesRegular), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachinePriorityTypesRegular), + string(compute.VirtualMachinePriorityTypesSpot), + }, false), + }, + + "provision_vm_agent": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + ForceNew: true, + }, + + "proximity_placement_group_id": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + // the Compute API is broken and returns the Resource Group name in UPPERCASE :shrug:, github issue: https://github.com/Azure/azure-rest-api-specs/issues/10016 + DiffSuppressFunc: suppress.CaseDifference, + }, + + "rolling_upgrade_policy": VirtualMachineScaleSetRollingUpgradePolicySchema(), + + "secret": windowsSecretSchema(), + + "secure_boot_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + }, + + "single_placement_group": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "source_image_id": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "source_image_reference": sourceImageReferenceSchema(false), + + "tags": tags.Schema(), + + "timezone": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: computeValidate.VirtualMachineTimeZone(), + }, + + "upgrade_mode": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(compute.UpgradeModeManual), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.UpgradeModeAutomatic), + string(compute.UpgradeModeManual), + string(compute.UpgradeModeRolling), + }, false), + }, + + "user_data": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsBase64, + }, + + "vtpm_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + }, + + "winrm_listener": winRmListenerSchema(), + + "zone_balance": { + Type: pluginsdk.TypeBool, + Optional: true, + ForceNew: true, + Default: false, + }, + + "scale_in_policy": { + Type: pluginsdk.TypeString, + Optional: true, + Default: string(compute.VirtualMachineScaleSetScaleInRulesDefault), + ValidateFunc: validation.StringInSlice([]string{ + string(compute.VirtualMachineScaleSetScaleInRulesDefault), + string(compute.VirtualMachineScaleSetScaleInRulesNewestVM), + string(compute.VirtualMachineScaleSetScaleInRulesOldestVM), + }, false), + }, + + "termination_notification": VirtualMachineScaleSetTerminationNotificationSchema(), + + "zones": func() *schema.Schema { + if !features.ThreePointOhBeta() { + return azure.SchemaZones() + } + + return commonschema.ZonesMultipleOptionalForceNew() + }(), + + // Computed + "unique_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + } + + if !features.FourPointOhBeta() { + out["terminate_notification"] = VirtualMachineScaleSetTerminateNotificationSchema() + } + + return out +} 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 3e116ce25a2a..8751cc455dce 100644 --- a/website/docs/r/linux_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/linux_virtual_machine_scale_set.html.markdown @@ -202,6 +202,10 @@ The following arguments are supported: * `terminate_notification` - (Optional) A `terminate_notification` block as defined below. +~> **Note:** This property has been deprecated in favour of the `termination_notification` property and will be removed in version 4.0 of the provider. + +* `termination_notification` - (Optional) A `termination_notification` block as defined below. + * `upgrade_mode` - (Optional) Specifies how Upgrades (e.g. changing the Image/SKU) should be performed to Virtual Machine Instances. Possible values are `Automatic`, `Manual` and `Rolling`. Defaults to `Manual`. * `user_data` - (Optional) The Base64-Encoded User Data which should be used for this Virtual Machine Scale Set. @@ -484,6 +488,16 @@ A `terminate_notification` block supports the following: --- +A `termination_notification` block supports the following: + +* `enabled` - (Required) Should the termination notification be enabled on this Virtual Machine Scale Set? Defaults to `false`. + +* `timeout` - (Optional) Length of time (in minutes, between 5 and 15) a notification to be sent to the VM on the instance metadata server till the VM gets deleted. The time duration should be specified in ISO 8601 format. + +~> **NOTE:** For more information about the termination notification, please [refer to this doc](https://docs.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-terminate-notification). + +--- + `source_image_reference` supports the following: * `publisher` - (Optional) Specifies the publisher of the image used to create the virtual machines. 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 9f1d283ab6c8..3239f5e3c55d 100644 --- a/website/docs/r/windows_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/windows_virtual_machine_scale_set.html.markdown @@ -192,6 +192,10 @@ The following arguments are supported: * `terminate_notification` - (Optional) A `terminate_notification` block as defined below. +~> **Note:** This property has been deprecated in favour of the `termination_notification` property and will be removed in version 4.0 of the provider. + +* `termination_notification` - (Optional) A `termination_notification` block as defined below. + * `timezone` - (Optional) Specifies the time zone of the virtual machine, [the possible values are defined here](https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/). * `upgrade_mode` - (Optional) Specifies how Upgrades (e.g. changing the Image/SKU) should be performed to Virtual Machine Instances. Possible values are `Automatic`, `Manual` and `Rolling`. Defaults to `Manual`. @@ -476,6 +480,16 @@ A `terminate_notification` block supports the following: --- +A `termination_notification` block supports the following: + +* `enabled` - (Required) Should the termination notification be enabled on this Virtual Machine Scale Set? Defaults to `false`. + +* `timeout` - (Optional) Length of time (in minutes, between 5 and 15) a notification to be sent to the VM on the instance metadata server till the VM gets deleted. The time duration should be specified in ISO 8601 format. + +~> **NOTE:** For more information about the termination notification, please [refer to this doc](https://docs.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-terminate-notification). + +--- + A `winrm_listener` block supports the following: * `certificate_url` - (Optional) The Secret URL of a Key Vault Certificate, which must be specified when `protocol` is set to `Https`.