diff --git a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_extensions_test.go b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_extensions_test.go index 2c6cf44ce42b..02d6e2e15a06 100644 --- a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_extensions_test.go +++ b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_extensions_test.go @@ -187,6 +187,28 @@ func TestAccLinuxVirtualMachineScaleSet_extensionsAutomaticUpgradeWithHealthExte }) } +func TestAccLinuxVirtualMachineScaleSet_extensionAutomaticUpgradeUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + r := LinuxVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.extensionsWithHealthExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password", "extension.0.protected_settings"), + { + Config: r.extensionsAutomaticUpgradeWithHealthExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password", "extension.0.protected_settings"), + }) +} + func TestAccLinuxVirtualMachineScaleSet_extensionWithTimeBudget(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") r := LinuxVirtualMachineScaleSetResource{} @@ -275,6 +297,21 @@ func TestAccLinuxVirtualMachineScaleSet_extensionTimeBudgetWithoutExtensionsUpda }) } +func TestAccLinuxVirtualMachineScaleSet_extensionsAutomaticUpgradeWithServiceFabricExtension(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + r := LinuxVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.extensionsAutomaticUpgradeWithServiceFabricExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password", "extension.0.protected_settings"), + }) +} + func (r LinuxVirtualMachineScaleSetResource) extensionDoNotRunExtensionsOnOverProvisionedMachines(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %s @@ -712,6 +749,60 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { `, r.template(data), data.RandomInteger) } +func (r LinuxVirtualMachineScaleSetResource) extensionsWithHealthExtension(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s +provider "azurerm" { + features {} +} +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 + upgrade_mode = "Automatic" + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + 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 + } + } + extension { + name = "HealthExtension" + publisher = "Microsoft.ManagedServices" + type = "ApplicationHealthLinux" + type_handler_version = "1.0" + auto_upgrade_minor_version = true + settings = jsonencode({ + protocol = "https" + port = 443 + }) + } + tags = { + accTest = "true" + } +} +`, r.template(data), data.RandomInteger) +} + func (r LinuxVirtualMachineScaleSetResource) extensionsAutomaticUpgradeWithHealthExtension(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s @@ -886,3 +977,98 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { } `, template, data.RandomInteger, duration) } + +func (r LinuxVirtualMachineScaleSetResource) extensionsAutomaticUpgradeWithServiceFabricExtension(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_service_fabric_cluster" "test" { + name = "acctest-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + reliability_level = "Silver" + upgrade_mode = "Manual" + cluster_code_version = "8.0.516.9590" + vm_image = "Windows" + management_endpoint = "http://example:80" + + node_type { + name = "backend" + instance_count = 5 + is_primary = true + client_endpoint_port = 2020 + http_endpoint_port = 80 + durability_level = "Silver" + } +} + +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!" + upgrade_mode = "Automatic" + overprovision = false + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + 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 + } + } + + automatic_os_upgrade_policy { + disable_automatic_rollback = true + enable_automatic_os_upgrade = true + } + + rolling_upgrade_policy { + max_batch_instance_percent = 20 + max_unhealthy_instance_percent = 20 + max_unhealthy_upgraded_instance_percent = 20 + pause_time_between_batches = "PT0S" + } + + extension { + name = "ServiceFabric" + publisher = "Microsoft.Azure.ServiceFabric" + type = "ServiceFabricLinuxNode" + type_handler_version = "1.1" + auto_upgrade_minor_version = true + + settings = jsonencode({ + clusterEndpoint = azurerm_service_fabric_cluster.test.cluster_endpoint + nodeTypeRef = "backend" + durabilityLevel = "Silver" + enableParallelJobs = true + }) + } +} +`, template, data.RandomInteger, data.RandomInteger) +} diff --git a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go index c3df5166b1d3..46de3149af60 100644 --- a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go +++ b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go @@ -430,14 +430,6 @@ func resourceLinuxVirtualMachineScaleSetCreate(d *schema.ResourceData, meta inte virtualMachineProfile.ExtensionProfile.ExtensionsTimeBudget = utils.String(v.(string)) } - // otherwise the service return the error: - // Automatic OS Upgrade is not supported for this Virtual Machine Scale Set because a health probe or health extension was not specified. - if upgradeMode == compute.Automatic && len(automaticOSUpgradePolicyRaw) > 0 { - if *automaticOSUpgradePolicy.EnableAutomaticOSUpgrade && (healthProbeId == "" && !hasHealthExtension) { - return fmt.Errorf("`health_probe_id` must be set or a health extension must be specified when `upgrade_mode` is set to %q and `automatic_os_upgrade_policy` block exists", string(upgradeMode)) - } - } - // otherwise the service return the error: // Rolling Upgrade mode is not supported for this Virtual Machine Scale Set because a health probe or health extension was not provided. if upgradeMode == compute.Rolling && (healthProbeId == "" && !hasHealthExtension) { diff --git a/azurerm/internal/services/compute/virtual_machine_scale_set.go b/azurerm/internal/services/compute/virtual_machine_scale_set.go index 3b36cf319e3a..61a56ffd35e3 100644 --- a/azurerm/internal/services/compute/virtual_machine_scale_set.go +++ b/azurerm/internal/services/compute/virtual_machine_scale_set.go @@ -1236,7 +1236,6 @@ func VirtualMachineScaleSetAutomatedOSUpgradePolicySchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, Optional: true, - ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -1244,12 +1243,10 @@ func VirtualMachineScaleSetAutomatedOSUpgradePolicySchema() *schema.Schema { "disable_automatic_rollback": { Type: schema.TypeBool, Required: true, - ForceNew: true, }, "enable_automatic_os_upgrade": { Type: schema.TypeBool, Required: true, - ForceNew: true, }, }, }, diff --git a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_extensions_test.go b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_extensions_test.go index 200d1a6155d3..9f4cb8d96afa 100644 --- a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_extensions_test.go +++ b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_extensions_test.go @@ -279,6 +279,47 @@ func TestAccWindowsVirtualMachineScaleSet_extensionTimeBudgetWithoutExtensionsUp }) } +func TestAccWindowsVirtualMachineScaleSet_extensionsAutomaticUpgradeWithServiceFabricExtension(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + r := WindowsVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.extensionsAutomaticUpgradeWithServiceFabricExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep( + "admin_password", + "extension.0.protected_settings", + "enable_automatic_updates", + ), + }) +} + +func TestAccWindowsVirtualMachineScaleSet_extensionAutomaticUpgradeUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + r := WindowsVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.extensionsWithHealthExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password", "extension.0.protected_settings", "enable_automatic_updates"), + { + Config: r.extensionsAutomaticUpgradeWithHealthExtension(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("admin_password", "extension.0.protected_settings", "enable_automatic_updates"), + }) +} + func (r WindowsVirtualMachineScaleSetResource) extensionDoNotRunOnOverProvisionedMachines(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` %s @@ -682,6 +723,63 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { `, r.template(data)) } +func (r WindowsVirtualMachineScaleSetResource) extensionsWithHealthExtension(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +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!" + upgrade_mode = "Automatic" + enable_automatic_updates = false + + 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 + } + } + + extension { + name = "HealthExtension" + publisher = "Microsoft.ManagedServices" + type = "ApplicationHealthWindows" + type_handler_version = "1.0" + auto_upgrade_minor_version = true + settings = jsonencode({ + protocol = "https" + port = 443 + requestPath = "/" + }) + } +} +`, r.template(data)) +} + func (r WindowsVirtualMachineScaleSetResource) extensionsAutomaticUpgradeWithHealthExtension(data acceptance.TestData) string { return fmt.Sprintf(` %s @@ -691,14 +789,15 @@ provider "azurerm" { } 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!" - upgrade_mode = "Automatic" + 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!" + upgrade_mode = "Automatic" + enable_automatic_updates = false automatic_os_upgrade_policy { disable_automatic_rollback = true @@ -857,3 +956,96 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { } `, template, duration) } + +func (r WindowsVirtualMachineScaleSetResource) extensionsAutomaticUpgradeWithServiceFabricExtension(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_service_fabric_cluster" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + reliability_level = "Silver" + upgrade_mode = "Manual" + cluster_code_version = "8.0.516.9590" + vm_image = "Windows" + management_endpoint = "http://example:80" + + node_type { + name = "backend" + instance_count = 5 + is_primary = true + client_endpoint_port = 2020 + http_endpoint_port = 80 + durability_level = "Silver" + } +} + +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!" + upgrade_mode = "Automatic" + enable_automatic_updates = false + overprovision = false + + automatic_os_upgrade_policy { + disable_automatic_rollback = true + enable_automatic_os_upgrade = true + } + + rolling_upgrade_policy { + max_batch_instance_percent = 20 + max_unhealthy_instance_percent = 20 + max_unhealthy_upgraded_instance_percent = 20 + pause_time_between_batches = "PT0S" + } + + 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 + } + } + + extension { + name = "ServiceFabric" + publisher = "Microsoft.Azure.ServiceFabric" + type = "ServiceFabricNode" + type_handler_version = "1.1" + auto_upgrade_minor_version = true + + settings = jsonencode({ + clusterEndpoint = azurerm_service_fabric_cluster.test.cluster_endpoint + nodeTypeRef = "backend" + dataPath = "C:\\SvcFab" + durabilityLevel = "Silver" + enableParallelJobs = true + }) + } +} +`, r.template(data)) +} diff --git a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go index 84025e84cb64..77b9778d8857 100644 --- a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go +++ b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go @@ -446,14 +446,6 @@ func resourceWindowsVirtualMachineScaleSetCreate(d *schema.ResourceData, meta in virtualMachineProfile.ExtensionProfile.ExtensionsTimeBudget = utils.String(v.(string)) } - // otherwise the service return the error: - // Automatic OS Upgrade is not supported for this Virtual Machine Scale Set because a health probe or health extension was not specified. - if upgradeMode == compute.Automatic && len(automaticOSUpgradePolicyRaw) > 0 { - if *automaticOSUpgradePolicy.EnableAutomaticOSUpgrade && (healthProbeId == "" && !hasHealthExtension) { - return fmt.Errorf("`health_probe_id` must be set or a health extension must be specified when `upgrade_mode` is set to %q and `automatic_os_upgrade_policy` block exists", string(upgradeMode)) - } - } - // otherwise the service return the error: // Rolling Upgrade mode is not supported for this Virtual Machine Scale Set because a health probe or health extension was not provided. if upgradeMode == compute.Rolling && (healthProbeId == "" && !hasHealthExtension) { 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 6b293b0f0bbe..d2a7f4a88c25 100644 --- a/website/docs/r/linux_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/linux_virtual_machine_scale_set.html.markdown @@ -226,9 +226,9 @@ A `admin_ssh_key` block supports the following: A `automatic_os_upgrade_policy` block supports the following: -* `disable_automatic_rollback` - (Required) Should automatic rollbacks be disabled? Changing this forces a new resource to be created. +* `disable_automatic_rollback` - (Required) Should automatic rollbacks be disabled? -* `enable_automatic_os_upgrade` - (Required) Should OS Upgrades automatically be applied to Scale Set instances in a rolling fashion when a newer version of the OS Image becomes available? Changing this forces a new resource to be created. +* `enable_automatic_os_upgrade` - (Required) Should OS Upgrades automatically be applied to Scale Set instances in a rolling fashion when a newer version of the OS Image becomes available? --- 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 d45ba6cf4ec4..1a59c52f2545 100644 --- a/website/docs/r/windows_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/windows_virtual_machine_scale_set.html.markdown @@ -216,9 +216,9 @@ A `additional_unattend_content` block supports the following: A `automatic_os_upgrade_policy` block supports the following: -* `disable_automatic_rollback` - (Required) Should automatic rollbacks be disabled? Changing this forces a new resource to be created. +* `disable_automatic_rollback` - (Required) Should automatic rollbacks be disabled? -* `enable_automatic_os_upgrade` - (Required) Should OS Upgrades automatically be applied to Scale Set instances in a rolling fashion when a newer version of the OS Image becomes available? Changing this forces a new resource to be created. +* `enable_automatic_os_upgrade` - (Required) Should OS Upgrades automatically be applied to Scale Set instances in a rolling fashion when a newer version of the OS Image becomes available? ---