diff --git a/azurerm/internal/services/mssql/mssql_virtual_machine_resource.go b/azurerm/internal/services/mssql/mssql_virtual_machine_resource.go index 14e6485cb9ff..de41464594ea 100644 --- a/azurerm/internal/services/mssql/mssql_virtual_machine_resource.go +++ b/azurerm/internal/services/mssql/mssql_virtual_machine_resource.go @@ -1,6 +1,7 @@ package mssql import ( + "context" "fmt" "log" "strings" @@ -8,6 +9,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/sqlvirtualmachine/mgmt/2017-03-01-preview/sqlvirtualmachine" "github.com/hashicorp/go-azure-helpers/response" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -20,6 +22,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mssql/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,6 +34,8 @@ func resourceMsSqlVirtualMachine() *schema.Resource { Update: resourceMsSqlVirtualMachineCreateUpdate, Delete: resourceMsSqlVirtualMachineDelete, + CustomizeDiff: resourceMsSqlVirtualMachineCustomDiff, + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { _, err := parse.SqlVirtualMachineID(id) return err @@ -61,6 +66,84 @@ func resourceMsSqlVirtualMachine() *schema.Resource { }, false), }, + "auto_backup": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "backup_system_databases": { + Type: schema.TypeBool, + Optional: true, + }, + + "backup_schedule_automated": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "encryption_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "encryption_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + + "full_backup_frequency": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(sqlvirtualmachine.Daily), + string(sqlvirtualmachine.Weekly), + }, false), + }, + + "full_backup_start_hour": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(0, 23), + }, + + "full_backup_window_hours": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 23), + }, + + "log_backup_frequency": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(5, 60), + }, + + "retention_period": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 30), + }, + + "storage_blob_endpoint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.IsURLWithHTTPS, + }, + + "storage_account_access_key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, + }, + "auto_patching": { Type: schema.TypeList, Optional: true, @@ -210,6 +293,55 @@ func resourceMsSqlVirtualMachine() *schema.Resource { } } +func resourceMsSqlVirtualMachineCustomDiff(d *schema.ResourceDiff, _ interface{}) error { + encryptionEnabled := d.Get("auto_backup.0.encryption_enabled") + v, ok := d.GetOk("auto_backup.0.encryption_password") + + if encryptionEnabled.(bool) && (!ok || v.(string) == "") { + return fmt.Errorf("auto_backup: `encryption_password` is required when `encryption_enabled` is true") + } + + if !encryptionEnabled.(bool) && ok && v.(string) != "" { + return fmt.Errorf("auto_backup: `encryption_enabled` must be true when `encryption_password` is set") + } + + if v, ok := d.GetOk("auto_backup.0.backup_schedule_automated"); ok && v.(bool) { + if _, ok := d.GetOk("auto_backup.0.full_backup_start_hour"); ok { + return fmt.Errorf("auto_backup: `full_backup_start_hour` can only be set when `backup_schedule_automated` is false") + } + + if _, ok := d.GetOk("auto_backup.0.full_backup_window_hours"); ok { + return fmt.Errorf("auto_backup: `full_backup_window_hours` can only be set when `backup_schedule_automated` is false") + } + + if _, ok := d.GetOk("auto_backup.0.log_backup_frequency"); ok { + return fmt.Errorf("auto_backup: `log_backup_frequency` can only be set when `backup_schedule_automated` is false") + } + + if _, ok := d.GetOk("auto_backup.0.full_backup_frequency"); ok { + return fmt.Errorf("auto_backup: `full_backup_frequency` can only be set when `backup_schedule_automated` is false") + } + } else { + if _, ok := d.GetOk("auto_backup.0.full_backup_start_hour"); !ok { + return fmt.Errorf("auto_backup: `full_backup_start_hour` must be set when `backup_schedule_automated` is false") + } + + if _, ok := d.GetOk("auto_backup.0.full_backup_window_hours"); !ok { + return fmt.Errorf("auto_backup: `full_backup_window_hours` must be set when `backup_schedule_automated` is false") + } + + if _, ok := d.GetOk("auto_backup.0.log_backup_frequency"); !ok { + return fmt.Errorf("auto_backup: `log_backup_frequency` must be set when `backup_schedule_automated` is false") + } + + if v, ok := d.GetOk("auto_backup.0.full_backup_frequency"); !ok || v.(string) == "" { + return fmt.Errorf("auto_backup: `full_backup_frequency` must be set when `backup_schedule_automated` is false") + } + } + + return nil +} + func resourceMsSqlVirtualMachineCreateUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*clients.Client).MSSQL.VirtualMachinesClient vmclient := meta.(*clients.Client).Compute.VMClient @@ -250,6 +382,7 @@ func resourceMsSqlVirtualMachineCreateUpdate(d *schema.ResourceData, meta interf VirtualMachineResourceID: utils.String(d.Get("virtual_machine_id").(string)), SQLServerLicenseType: sqlvirtualmachine.SQLServerLicenseType(d.Get("sql_license_type").(string)), SQLManagement: sqlvirtualmachine.Full, + AutoBackupSettings: expandSqlVirtualMachineAutoBackupSettings(d.Get("auto_backup").([]interface{})), AutoPatchingSettings: expandSqlVirtualMachineAutoPatchingSettings(d.Get("auto_patching").([]interface{})), KeyVaultCredentialSettings: expandSqlVirtualMachineKeyVaultCredential(d.Get("key_vault_credential").([]interface{})), ServerConfigurationsManagementSettings: &sqlvirtualmachine.ServerConfigurationsManagementSettings{ @@ -283,8 +416,30 @@ func resourceMsSqlVirtualMachineCreateUpdate(d *schema.ResourceData, meta interf if resp.ID == nil { return fmt.Errorf("Cannot read Sql Virtual Machine (Sql Virtual Machine Name %q / Resource Group %q) ID", id.Name, id.ResourceGroup) } + d.SetId(*resp.ID) + // Wait for the auto backup settings to take effect + // See: https://github.com/Azure/azure-rest-api-specs/issues/12818 + log.Printf("[DEBUG] Waiting for SQL Virtual Machine %q AutoBackupSettings to take effect", d.Id()) + stateConf := &resource.StateChangeConf{ + Pending: []string{"Retry", "Pending"}, + Target: []string{"Updated"}, + Refresh: resourceMsSqlVirtualMachineAutoBackupSettingsRefreshFunc(ctx, client, d), + MinTimeout: 1 * time.Minute, + ContinuousTargetOccurence: 2, + } + + if d.IsNewResource() { + stateConf.Timeout = d.Timeout(schema.TimeoutCreate) + } else { + stateConf.Timeout = d.Timeout(schema.TimeoutUpdate) + } + + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("waiting for SQL Virtual Machine %q AutoBackupSettings to take effect: %+v", d.Id(), err) + } + return resourceMsSqlVirtualMachineRead(d, meta) } @@ -311,6 +466,10 @@ func resourceMsSqlVirtualMachineRead(d *schema.ResourceData, meta interface{}) e if props := resp.Properties; props != nil { d.Set("virtual_machine_id", props.VirtualMachineResourceID) d.Set("sql_license_type", string(props.SQLServerLicenseType)) + if err := d.Set("auto_backup", flattenSqlVirtualMachineAutoBackup(props.AutoBackupSettings, d)); err != nil { + return fmt.Errorf("setting `auto_backup`: %+v", err) + } + if err := d.Set("auto_patching", flattenSqlVirtualMachineAutoPatching(props.AutoPatchingSettings)); err != nil { return fmt.Errorf("setting `auto_patching`: %+v", err) } @@ -367,6 +526,153 @@ func resourceMsSqlVirtualMachineDelete(d *schema.ResourceData, meta interface{}) return nil } +func resourceMsSqlVirtualMachineAutoBackupSettingsRefreshFunc(ctx context.Context, client *sqlvirtualmachine.SQLVirtualMachinesClient, d *schema.ResourceData) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + id, err := parse.SqlVirtualMachineID(d.Id()) + if err != nil { + return nil, "Error", err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "*") + if err != nil { + return nil, "Retry", err + } + + if props := resp.Properties; props != nil { + autoBackupSettings := flattenSqlVirtualMachineAutoBackup(props.AutoBackupSettings, d) + + if len(autoBackupSettings) == 0 { + // auto backup was nil or disabled in the response + if v, ok := d.GetOk("auto_backup"); !ok || len(v.([]interface{})) == 0 { + // also disabled in the config + return resp, "Updated", nil + } + return resp, "Pending", nil + } + + if v, ok := d.GetOk("auto_backup"); !ok || len(v.([]interface{})) == 0 { + // still waiting for it to be disabled + return resp, "Pending", nil + } + + // check each property for drift + for prop, val := range autoBackupSettings[0].(map[string]interface{}) { + v := d.Get(fmt.Sprintf("auto_backup.0.%s", prop)) + switch prop { + case "full_backup_frequency": + if !strings.EqualFold(v.(string), val.(string)) { + return resp, "Pending", nil + } + default: + if v != val { + return resp, "Pending", nil + } + } + } + + return resp, "Updated", nil + } + + return resp, "Retry", nil + } +} + +func expandSqlVirtualMachineAutoBackupSettings(input []interface{}) *sqlvirtualmachine.AutoBackupSettings { + ret := sqlvirtualmachine.AutoBackupSettings{ + Enable: utils.Bool(false), + } + + if len(input) == 1 { + config := input[0].(map[string]interface{}) + + ret.Enable = utils.Bool(true) + ret.RetentionPeriod = utils.Int32(int32(config["retention_period"].(int))) + ret.StorageAccountURL = utils.String(config["storage_blob_endpoint"].(string)) + ret.StorageAccessKey = utils.String(config["storage_account_access_key"].(string)) + + v, ok := config["encryption_enabled"] + enableEncryption := ok && v.(bool) + ret.EnableEncryption = utils.Bool(enableEncryption) + if enableEncryption { + ret.Password = utils.String(config["encryption_password"].(string)) + } + + if v, ok := config["backup_system_databases"]; ok { + ret.BackupSystemDbs = utils.Bool(v.(bool)) + } + + if v, ok := config["backup_schedule_automated"]; ok && v.(bool) { + ret.BackupScheduleType = sqlvirtualmachine.Automated + } else { + ret.BackupScheduleType = sqlvirtualmachine.Manual + ret.FullBackupFrequency = sqlvirtualmachine.FullBackupFrequencyType(config["full_backup_frequency"].(string)) + + if v, ok := config["full_backup_start_hour"]; ok { + ret.FullBackupStartTime = utils.Int32(int32(v.(int))) + } + + if v, ok := config["full_backup_window_hours"]; ok { + ret.FullBackupWindowHours = utils.Int32(int32(v.(int))) + } + + if v, ok := config["log_backup_frequency"]; ok { + ret.LogBackupFrequency = utils.Int32(int32(v.(int))) + } + } + } + + return &ret +} + +func flattenSqlVirtualMachineAutoBackup(autoBackup *sqlvirtualmachine.AutoBackupSettings, d *schema.ResourceData) []interface{} { + if autoBackup == nil || autoBackup.Enable == nil || !*autoBackup.Enable { + return []interface{}{} + } + + var fullBackupStartHour int + if autoBackup.FullBackupStartTime != nil { + fullBackupStartHour = int(*autoBackup.FullBackupStartTime) + } + + var fullBackupWindowHours int + if autoBackup.FullBackupWindowHours != nil { + fullBackupWindowHours = int(*autoBackup.FullBackupWindowHours) + } + + var logBackupFrequency int + if autoBackup.LogBackupFrequency != nil { + logBackupFrequency = int(*autoBackup.LogBackupFrequency) + } + + var retentionPeriod int + if autoBackup.RetentionPeriod != nil { + retentionPeriod = int(*autoBackup.RetentionPeriod) + } + + // Password, StorageAccessKey, StorageAccountURL are not returned, so we try to copy them + // from existing config as a best effort. + encryptionPassword := d.Get("auto_backup.0.encryption_password").(string) + storageKey := d.Get("auto_backup.0.storage_account_access_key").(string) + blobEndpoint := d.Get("auto_backup.0.storage_blob_endpoint").(string) + + return []interface{}{ + map[string]interface{}{ + "backup_schedule_automated": strings.EqualFold(string(autoBackup.BackupScheduleType), string(sqlvirtualmachine.Automated)), + "backup_system_databases": autoBackup.BackupSystemDbs != nil && *autoBackup.BackupSystemDbs, + "encryption_enabled": autoBackup.EnableEncryption != nil && *autoBackup.EnableEncryption, + "full_backup_frequency": string(autoBackup.FullBackupFrequency), + "full_backup_start_hour": fullBackupStartHour, + "full_backup_window_hours": fullBackupWindowHours, + "log_backup_frequency": logBackupFrequency, + "retention_period": retentionPeriod, + + "encryption_password": encryptionPassword, + "storage_account_access_key": storageKey, + "storage_blob_endpoint": blobEndpoint, + }, + } +} + func expandSqlVirtualMachineAutoPatchingSettings(input []interface{}) *sqlvirtualmachine.AutoPatchingSettings { if len(input) == 0 { return nil diff --git a/azurerm/internal/services/mssql/mssql_virtual_machine_resource_test.go b/azurerm/internal/services/mssql/mssql_virtual_machine_resource_test.go index 7a14742d02cb..599fb7e62e47 100644 --- a/azurerm/internal/services/mssql/mssql_virtual_machine_resource_test.go +++ b/azurerm/internal/services/mssql/mssql_virtual_machine_resource_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" @@ -70,7 +71,49 @@ func TestAccMsSqlVirtualMachine_complete(t *testing.T) { }) } -func TestAccMsSqlVirtualMachine_withAutoPatching(t *testing.T) { +func TestAccMsSqlVirtualMachine_autoBackup(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_mssql_virtual_machine", "test") + r := MsSqlVirtualMachineResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.withAutoBackupAutoSchedule(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("auto_backup.0.encryption_password", + "auto_backup.0.storage_account_access_key", + "auto_backup.0.storage_blob_endpoint"), + { + Config: r.withAutoBackupManualSchedule(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("auto_backup.0.encryption_password", + "auto_backup.0.storage_account_access_key", + "auto_backup.0.storage_blob_endpoint"), + { + Config: r.withAutoBackupAutoSchedule(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("auto_backup.0.encryption_password", + "auto_backup.0.storage_account_access_key", + "auto_backup.0.storage_blob_endpoint"), + { + Config: r.basic(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccMsSqlVirtualMachine_autoPatching(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_mssql_virtual_machine", "test") r := MsSqlVirtualMachineResource{} @@ -92,9 +135,8 @@ func TestAccMsSqlVirtualMachine_withAutoPatching(t *testing.T) { }) } -func TestAccMsSqlVirtualMachine_withKeyVault(t *testing.T) { +func TestAccMsSqlVirtualMachine_keyVault(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_mssql_virtual_machine", "test") - r := MsSqlVirtualMachineResource{} value, err := uuid.GenerateUUID() if err != nil { @@ -106,7 +148,7 @@ func TestAccMsSqlVirtualMachine_withKeyVault(t *testing.T) { Config: r.withKeyVault(data, value), Check: resource.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("key_vault_credential.0.name").MatchesRegex(regexp.MustCompile("/*:acctestkv")), + check.That(data.ResourceName).Key("r_services_enabled").MatchesRegex(regexp.MustCompile("/*:acctestkv")), ), }, data.ImportStep("key_vault_credential.0.key_vault_url", "key_vault_credential.0.service_principal_name", "key_vault_credential.0.service_principal_secret"), @@ -115,20 +157,20 @@ func TestAccMsSqlVirtualMachine_withKeyVault(t *testing.T) { Config: r.withKeyVaultUpdated(data, value), Check: resource.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("key_vault_credential.0.name").MatchesRegex(regexp.MustCompile("/*:acctestkv2")), + check.That(data.ResourceName).Key("r_services_enabled").MatchesRegex(regexp.MustCompile("/*:acctestkv2")), ), }, data.ImportStep("key_vault_credential.0.key_vault_url", "key_vault_credential.0.service_principal_name", "key_vault_credential.0.service_principal_secret"), }) } -func TestAccMsSqlVirtualMachine_withStorageConfiguration(t *testing.T) { +func TestAccMsSqlVirtualMachine_storageConfiguration(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_mssql_virtual_machine", "test") r := MsSqlVirtualMachineResource{} data.ResourceTest(t, r, []resource.TestStep{ { - Config: r.withStorageConfiguration(data), + Config: r.storageConfiguration(data), Check: resource.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -369,6 +411,66 @@ resource "azurerm_mssql_virtual_machine" "test" { `, r.template(data)) } +func (r MsSqlVirtualMachineResource) withAutoBackupAutoSchedule(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_storage_account" "test" { + name = "unlikely23exst2acct%[2]s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_mssql_virtual_machine" "test" { + virtual_machine_id = azurerm_virtual_machine.test.id + sql_license_type = "PAYG" + + auto_backup { + encryption_enabled = true + encryption_password = "P@55w0rD!!%[2]s" + retention_period = 23 + storage_blob_endpoint = azurerm_storage_account.test.primary_blob_endpoint + storage_account_access_key = azurerm_storage_account.test.primary_access_key + } +} +`, r.template(data), data.RandomString) +} + +func (r MsSqlVirtualMachineResource) withAutoBackupManualSchedule(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_storage_account" "test" { + name = "unlikely23exst2acct%[2]s" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_mssql_virtual_machine" "test" { + virtual_machine_id = azurerm_virtual_machine.test.id + sql_license_type = "PAYG" + + auto_backup { + encryption_enabled = true + encryption_password = "P@55w0rD!!%[2]s" + retention_period = 14 + storage_blob_endpoint = azurerm_storage_account.test.primary_blob_endpoint + storage_account_access_key = azurerm_storage_account.test.primary_access_key + backup_system_databases = true + backup_schedule_automated = false + full_backup_frequency = "Daily" + full_backup_start_hour = 3 + full_backup_window_hours = 4 + log_backup_frequency = 20 + } +} +`, r.template(data), data.RandomString) +} + func (r MsSqlVirtualMachineResource) withKeyVault(data acceptance.TestData, value string) string { return fmt.Sprintf(` %[1]s @@ -434,7 +536,7 @@ resource "azuread_service_principal" "test" { resource "azuread_service_principal_password" "test" { service_principal_id = azuread_service_principal.test.id value = "%[3]s" - end_date_relative = "240h" + end_date = "2021-01-01T01:02:03Z" } resource "azurerm_mssql_virtual_machine" "test" { @@ -514,7 +616,7 @@ resource "azuread_service_principal" "test" { resource "azuread_service_principal_password" "test" { service_principal_id = azuread_service_principal.test.id value = "%[3]s" - end_date_relative = "240h" + end_date = "2021-01-01T01:02:03Z" } resource "azurerm_mssql_virtual_machine" "test" { @@ -530,7 +632,7 @@ resource "azurerm_mssql_virtual_machine" "test" { `, r.template(data), data.RandomInteger, value) } -func (r MsSqlVirtualMachineResource) withStorageConfiguration(data acceptance.TestData) string { +func (r MsSqlVirtualMachineResource) storageConfiguration(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s diff --git a/website/docs/r/mssql_virtual_machine.html.markdown b/website/docs/r/mssql_virtual_machine.html.markdown index e17c3ea9b734..47ab472f9998 100644 --- a/website/docs/r/mssql_virtual_machine.html.markdown +++ b/website/docs/r/mssql_virtual_machine.html.markdown @@ -46,6 +46,8 @@ The following arguments are supported: * `sql_license_type` - (Optional) The SQL Server license type. Possible values are `AHUB` (Azure Hybrid Benefit) and `PAYG` (Pay-As-You-Go). Changing this forces a new resource to be created. +* `auto_backup` (Optional) An `auto_backup` block as defined below. + * `auto_patching` - (Optional) An `auto_patching` block as defined below. * `key_vault_credential` - (Optional) (Optional) An `key_vault_credential` block as defined below. @@ -66,6 +68,34 @@ The following arguments are supported: --- +The `auto_backup` block supports the following: + +* `backup_system_databases` - (Optional) Include or exclude system databases from auto backup. Defaults to `false`. + +* `backup_schedule_automated` - (Optional) Whether the backup schedule type is Automated. Defaults to `true`. + +-> NOTE: When `backup_shedule_automated` is true (which is the default), the scheduling properties `full_backup_frequency`, `full_backup_start_hour`, `full_backup_window_hours` and `log_backup_frequency` cannot be specified. When `backup_schedule_automated` is false, these properties must be set. + +* `encryption_enabled` - (Optional) Enable or disable encryption for backups. Defaults to `false`. + +* `encryption_password` - (Optional) Encryption password to use. Must be specified when encryption is enabled. + +* `full_backup_frequency` - (Optional) Frequency of full backups. Valid values include `Daily` or `Weekly`. Required when `backup_schedule_automated` is false. + +* `full_backup_start_hour` - (Optional) Start hour of a given day during which full backups can take place. Valid values are from `0` to `23`. Required when `backup_schedule_automated` is false. + +* `full_backup_window_hours` - (Optional) Duration of the time window of a given day during which full backups can take place, in hours. Valid values are between `1` and `23`. Required when `backup_schedule_automated` is false. + +* `log_backup_frequency` - (Optional) Frequency of log backups, in minutes. Valid values are from `5` to `60`. Required when `backup_schedule_automated` is false. + +* `retention_period` - (Required) Retention period of backups, in days. Valid values are from `1` to `30`. + +* `storage_blob_endpoint` - (Required) Blob endpoint for the storage account where backups will be kept. + +* `storage_account_access_key` - (Required) Access key for the storage account where backups will be kept. + +--- + The `auto_patching` block supports the following: * `day_of_week` - (Required) The day of week to apply the patch on.