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 ec21373326b1..478b4df57bd1 100644 --- a/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go +++ b/internal/services/compute/orchestrated_virtual_machine_scale_set_resource.go @@ -247,6 +247,8 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { }, }, + "rolling_upgrade_policy": VirtualMachineScaleSetRollingUpgradePolicySchema(), + // NOTE: single_placement_group is now supported in orchestrated VMSS // Since null is now a valid value for this field there is no default // for this bool @@ -294,6 +296,18 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { Computed: true, }, + "upgrade_mode": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: string(virtualmachinescalesets.UpgradeModeManual), + ValidateFunc: validation.StringInSlice([]string{ + string(virtualmachinescalesets.UpgradeModeAutomatic), + string(virtualmachinescalesets.UpgradeModeManual), + string(virtualmachinescalesets.UpgradeModeRolling), + }, false), + }, + "user_data_base64": { Type: pluginsdk.TypeString, Optional: true, @@ -341,6 +355,32 @@ func resourceOrchestratedVirtualMachineScaleSet() *pluginsdk.Resource { } } + upgradeMode := virtualmachinescalesets.UpgradeMode(diff.Get("upgrade_mode").(string)) + rollingUpgradePolicyRaw := diff.Get("rolling_upgrade_policy").([]interface{}) + + shouldHaveRollingUpgradePolicy := upgradeMode == virtualmachinescalesets.UpgradeModeAutomatic || upgradeMode == virtualmachinescalesets.UpgradeModeRolling + if !shouldHaveRollingUpgradePolicy && len(rollingUpgradePolicyRaw) > 0 { + return fmt.Errorf("a `rolling_upgrade_policy` block cannot be specified when `upgrade_mode` is set to %q", string(upgradeMode)) + } + shouldHaveRollingUpgradePolicy = upgradeMode == virtualmachinescalesets.UpgradeModeRolling + if shouldHaveRollingUpgradePolicy && len(rollingUpgradePolicyRaw) == 0 { + return fmt.Errorf("a `rolling_upgrade_policy` block must be specified when `upgrade_mode` is set to %q", string(upgradeMode)) + } + + hasHealthExtension := false + if v, ok := diff.GetOk("extension"); ok { + var err error + _, hasHealthExtension, err = expandOrchestratedVirtualMachineScaleSetExtensions(v.(*pluginsdk.Set).List()) + if err != nil { + return err + } + } + + // Virtual Machine Scale Set with Flexible Orchestration Mode and 'Rolling' upgradeMode must have Health Extension Present + if upgradeMode == virtualmachinescalesets.UpgradeModeRolling && !hasHealthExtension { + return fmt.Errorf("a health extension must be specified when `upgrade_mode` is set to Rolling") + } + return nil }), ), @@ -397,6 +437,18 @@ func resourceOrchestratedVirtualMachineScaleSetCreate(d *pluginsdk.ResourceData, props.Zones = &zones } + upgradeMode := virtualmachinescalesets.UpgradeMode(d.Get("upgrade_mode").(string)) + rollingUpgradePolicyRaw := d.Get("rolling_upgrade_policy").([]interface{}) + rollingUpgradePolicy, err := ExpandVirtualMachineScaleSetRollingUpgradePolicy(rollingUpgradePolicyRaw, len(zones) > 0, false) + if err != nil { + return err + } + + props.Properties.UpgradePolicy = &virtualmachinescalesets.UpgradePolicy{ + Mode: pointer.To(upgradeMode), + RollingUpgradePolicy: rollingUpgradePolicy, + } + virtualMachineProfile := virtualmachinescalesets.VirtualMachineScaleSetVMProfile{ StorageProfile: &virtualmachinescalesets.VirtualMachineScaleSetStorageProfile{}, } @@ -1160,6 +1212,28 @@ func resourceOrchestratedVirtualMachineScaleSetUpdate(d *pluginsdk.ResourceData, update.Zones = pointer.To(zones.ExpandUntyped(d.Get("zones").(*schema.Set).List())) } + if d.HasChange("rolling_upgrade_policy") { + upgradePolicy := virtualmachinescalesets.UpgradePolicy{} + if existing.Model.Properties.UpgradePolicy == nil { + upgradePolicy = virtualmachinescalesets.UpgradePolicy{ + Mode: pointer.To(virtualmachinescalesets.UpgradeMode(d.Get("upgrade_mode").(string))), + } + } else { + upgradePolicy = *existing.Model.Properties.UpgradePolicy + upgradePolicy.Mode = pointer.To(virtualmachinescalesets.UpgradeMode(d.Get("upgrade_mode").(string))) + } + + rollingRaw := d.Get("rolling_upgrade_policy").([]interface{}) + zones := zones.ExpandUntyped(d.Get("zones").(*schema.Set).List()) + rollingUpgradePolicy, err := ExpandVirtualMachineScaleSetRollingUpgradePolicy(rollingRaw, len(zones) > 0, false) + if err != nil { + return err + } + + upgradePolicy.RollingUpgradePolicy = rollingUpgradePolicy + updateProps.UpgradePolicy = &upgradePolicy + } + // 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 { @@ -1396,6 +1470,15 @@ func resourceOrchestratedVirtualMachineScaleSetRead(d *pluginsdk.ResourceData, m } d.Set("extension_operations_enabled", extensionOperationsEnabled) + + if policy := props.UpgradePolicy; policy != nil { + d.Set("upgrade_mode", string(pointer.From(policy.Mode))) + + flattenedRolling := FlattenVirtualMachineScaleSetRollingUpgradePolicy(policy.RollingUpgradePolicy) + if err := d.Set("rolling_upgrade_policy", flattenedRolling); err != nil { + return fmt.Errorf("setting `rolling_upgrade_policy`: %+v", err) + } + } } return tags.FlattenAndSet(d, model.Tags) } 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 3e2bf4be613d..eb6eb7f1ae8e 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 @@ -266,6 +266,63 @@ func TestAccOrchestratedVirtualMachineScaleSet_otherUltraSsd(t *testing.T) { }) } +func TestAccOrchestratedVirtualMachineScaleSet_otherUpgradePolicy(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") + r := OrchestratedVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.otherUpgradePolicy(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("os_profile.0.linux_configuration.0.admin_password"), + { + Config: r.otherUpgradePolicyUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("os_profile.0.linux_configuration.0.admin_password"), + }) +} + +func TestAccOrchestratedVirtualMachineScaleSet_otherRollingUpgrade(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") + r := OrchestratedVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.otherRollingUpgrade(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("os_profile.0.linux_configuration.0.admin_password"), + }) +} + +func TestAccOrchestratedVirtualMachineScaleSet_otherUpgradePolicyErrorValidation(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") + r := OrchestratedVirtualMachineScaleSetResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.otherRollingWithoutHealthExtension(data), + ExpectError: regexp.MustCompile("a health extension must be specified when `upgrade_mode` is set to Rolling"), + }, + { + Config: r.otherManualWithUpgradePolicy(data), + ExpectError: regexp.MustCompile("a `rolling_upgrade_policy` block cannot be specified"), + }, + { + Config: r.otherRollingWithoutUpgradePolicy(data), + ExpectError: regexp.MustCompile("a `rolling_upgrade_policy` block must be specified when `upgrade_mode` is set"), + }, + }) +} + func TestAccOrchestratedVirtualMachineScaleSet_otherCapacityReservationGroupId(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_orchestrated_virtual_machine_scale_set", "test") r := OrchestratedVirtualMachineScaleSetResource{} @@ -1514,6 +1571,457 @@ resource "azurerm_orchestrated_virtual_machine_scale_set" "test" { `, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data), data.RandomString, userData) } +func (OrchestratedVirtualMachineScaleSetResource) otherUpgradePolicy(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Automatic" + zones = ["1"] + + rolling_upgrade_policy { + cross_zone_upgrades_enabled = true + max_batch_instance_percent = 10 + max_unhealthy_instance_percent = 10 + max_unhealthy_upgraded_instance_percent = 10 + pause_time_between_batches = "PT0S" + prioritize_unhealthy_instances_enabled = true + maximum_surge_instances_enabled = false + } + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + +func (OrchestratedVirtualMachineScaleSetResource) otherUpgradePolicyUpdate(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Automatic" + zones = ["1"] + + rolling_upgrade_policy { + cross_zone_upgrades_enabled = false + max_batch_instance_percent = 20 + max_unhealthy_instance_percent = 20 + max_unhealthy_upgraded_instance_percent = 20 + pause_time_between_batches = "PT1S" + prioritize_unhealthy_instances_enabled = false + maximum_surge_instances_enabled = true + } + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + +func (OrchestratedVirtualMachineScaleSetResource) otherRollingUpgrade(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Rolling" + zones = ["1"] + + rolling_upgrade_policy { + cross_zone_upgrades_enabled = true + max_batch_instance_percent = 10 + max_unhealthy_instance_percent = 10 + max_unhealthy_upgraded_instance_percent = 10 + pause_time_between_batches = "PT0S" + prioritize_unhealthy_instances_enabled = true + maximum_surge_instances_enabled = false + } + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } + + extension { + name = "HealthExtension" + publisher = "Microsoft.ManagedServices" + type = "ApplicationHealthLinux" + type_handler_version = "1.0" + settings = jsonencode({ + protocol = "https" + port = 443 + }) + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + +func (OrchestratedVirtualMachineScaleSetResource) otherRollingWithoutHealthExtension(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Rolling" + zones = ["1"] + + rolling_upgrade_policy { + cross_zone_upgrades_enabled = true + max_batch_instance_percent = 10 + max_unhealthy_instance_percent = 10 + max_unhealthy_upgraded_instance_percent = 10 + pause_time_between_batches = "PT0S" + prioritize_unhealthy_instances_enabled = true + maximum_surge_instances_enabled = false + } + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + +func (OrchestratedVirtualMachineScaleSetResource) otherManualWithUpgradePolicy(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Manual" + zones = ["1"] + + rolling_upgrade_policy { + cross_zone_upgrades_enabled = true + max_batch_instance_percent = 10 + max_unhealthy_instance_percent = 10 + max_unhealthy_upgraded_instance_percent = 10 + pause_time_between_batches = "PT0S" + prioritize_unhealthy_instances_enabled = true + maximum_surge_instances_enabled = false + } + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + +func (OrchestratedVirtualMachineScaleSetResource) otherRollingWithoutUpgradePolicy(data acceptance.TestData) string { + r := OrchestratedVirtualMachineScaleSetResource{} + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-OVMSS-%[1]d" + location = "%[2]s" +} + +%[3]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 + sku_name = "Standard_D1_v2" + instances = 2 + platform_fault_domain_count = 1 + upgrade_mode = "Rolling" + zones = ["1"] + + os_profile { + linux_configuration { + computer_name_prefix = "testvm-%[1]d" + admin_username = "myadmin" + admin_password = "Passwword1234" + disable_password_authentication = false + } + } + + network_interface { + name = "TestNetworkProfile-%[1]d" + primary = true + + ip_configuration { + name = "TestIPConfiguration" + primary = true + subnet_id = azurerm_subnet.test.id + + public_ip_address { + name = "TestPublicIPConfiguration" + domain_name_label = "test-domain-label" + idle_timeout_in_minutes = 4 + } + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} +`, data.RandomInteger, data.Locations.Primary, r.natgateway_template(data)) +} + func (OrchestratedVirtualMachineScaleSetResource) otherCapacityReservationGroupId(data acceptance.TestData) string { r := OrchestratedVirtualMachineScaleSetResource{} return fmt.Sprintf(` 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 5dcfe85f157e..11ff0b457433 100644 --- a/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/orchestrated_virtual_machine_scale_set.html.markdown @@ -109,10 +109,14 @@ resource "azurerm_orchestrated_virtual_machine_scale_set" "example" { * `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`. Changing this forces a new resource to be created. + * `user_data_base64` - (Optional) The Base64-Encoded User Data which should be used for this Virtual Machine Scale Set. * `proximity_placement_group_id` - (Optional) The ID of the Proximity Placement Group which the Virtual Machine should be assigned to. Changing this forces a new resource to be created. +* `rolling_upgrade_policy` - (Optional) A `rolling_upgrade_policy` block as defined below. This is Required and can only be specified when `upgrade_mode` is set to `Automatic` or `Rolling`. Changing this forces a new resource to be created. + * `zone_balance` - (Optional) Should the Virtual Machines in this Scale Set be strictly evenly distributed across Availability Zones? Defaults to `false`. Changing this forces a new resource to be created. -> **Note:** This can only be set to `true` when one or more `zones` are configured. @@ -217,6 +221,24 @@ A `linux_configuration` block supports the following: --- +A `rolling_upgrade_policy` block supports the following: + +* `cross_zone_upgrades_enabled` - (Optional) Should the Virtual Machine Scale Set ignore the Azure Zone boundaries when constructing upgrade batches? Possible values are `true` or `false`. + +* `max_batch_instance_percent` - (Required) The maximum percent of total virtual machine instances that will be upgraded simultaneously by the rolling upgrade in one batch. As this is a maximum, unhealthy instances in previous or future batches can cause the percentage of instances in a batch to decrease to ensure higher reliability. + +* `max_unhealthy_instance_percent` - (Required) The maximum percentage of the total virtual machine instances in the scale set that can be simultaneously unhealthy, either as a result of being upgraded, or by being found in an unhealthy state by the virtual machine health checks before the rolling upgrade aborts. This constraint will be checked prior to starting any batch. + +* `max_unhealthy_upgraded_instance_percent` - (Required) The maximum percentage of upgraded virtual machine instances that can be found to be in an unhealthy state. This check will happen after each batch is upgraded. If this percentage is ever exceeded, the rolling update aborts. + +* `pause_time_between_batches` - (Required) The wait time between completing the update for all virtual machines in one batch and starting the next batch. The time duration should be specified in ISO 8601 format. + +* `prioritize_unhealthy_instances_enabled` - (Optional) Upgrade all unhealthy instances in a scale set before any healthy instances. Possible values are `true` or `false`. + +* `maximum_surge_instances_enabled` - (Optional) Create new virtual machines to upgrade the scale set, rather than updating the existing virtual machines. Existing virtual machines will be deleted once the new virtual machines are created for each batch. Possible values are `true` or `false`. + +--- + A `secret` block supports the following: * `key_vault_id` - (Required) The ID of the Key Vault from which all Secrets should be sourced.