Skip to content

Commit

Permalink
azurerm_data_protection_backup_vault : support new property `cross_…
Browse files Browse the repository at this point in the history
…region_restore_enabled` (hashicorp#27197)
  • Loading branch information
sinbai authored Sep 13, 2024
1 parent 0dcaf8c commit 252b9e5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ func resourceDataProtectionBackupVault() *pluginsdk.Resource {
}, false),
},

"cross_region_restore_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
},

"identity": commonschema.SystemAssignedIdentityOptional(),

"retention_duration_in_days": {
Expand All @@ -94,6 +99,21 @@ func resourceDataProtectionBackupVault() *pluginsdk.Resource {
pluginsdk.ForceNewIfChange("soft_delete", func(ctx context.Context, old, new, meta interface{}) bool {
return old.(string) == string(backupvaults.SoftDeleteStateAlwaysOn) && new.(string) != string(backupvaults.SoftDeleteStateAlwaysOn)
}),

// Once `cross_region_restore_enabled` is enabled it cannot be disabled.
pluginsdk.ForceNewIfChange("cross_region_restore_enabled", func(ctx context.Context, old, new, meta interface{}) bool {
return old.(bool) && new.(bool) != old.(bool)
}),

pluginsdk.CustomizeDiffShim(func(ctx context.Context, d *pluginsdk.ResourceDiff, v interface{}) error {
redundancy := d.Get("redundancy").(string)
crossRegionRestore := d.GetRawConfig().AsValueMap()["cross_region_restore_enabled"]
if !crossRegionRestore.IsNull() && redundancy != string(backupvaults.StorageSettingTypesGeoRedundant) {
// Cross region restore is only allowed on `GeoRedundant` vault.
return fmt.Errorf("`cross_region_restore_enabled` can only be specified when `redundancy` is specified for `GeoRedundant`.")
}
return nil
}),
),
}

Expand Down Expand Up @@ -175,6 +195,17 @@ func resourceDataProtectionBackupVaultCreateUpdate(d *pluginsdk.ResourceData, me
Tags: expandTags(d.Get("tags").(map[string]interface{})),
}

if !pluginsdk.IsExplicitlyNullInConfig(d, "cross_region_restore_enabled") {
parameters.Properties.FeatureSettings = &backupvaults.FeatureSettings{
CrossRegionRestoreSettings: &backupvaults.CrossRegionRestoreSettings{},
}
if d.Get("cross_region_restore_enabled").(bool) {
parameters.Properties.FeatureSettings.CrossRegionRestoreSettings.State = pointer.To(backupvaults.CrossRegionRestoreStateEnabled)
} else {
parameters.Properties.FeatureSettings.CrossRegionRestoreSettings.State = pointer.To(backupvaults.CrossRegionRestoreStateDisabled)
}
}

if v, ok := d.GetOk("retention_duration_in_days"); ok {
parameters.Properties.SecuritySettings.SoftDeleteSettings.RetentionDurationInDays = pointer.To(v.(float64))
}
Expand Down Expand Up @@ -223,6 +254,16 @@ func resourceDataProtectionBackupVaultRead(d *pluginsdk.ResourceData, meta inter
d.Set("retention_duration_in_days", pointer.From(softDelete.RetentionDurationInDays))
}
}
crossRegionStoreEnabled := false
if featureSetting := model.Properties.FeatureSettings; featureSetting != nil {
if featureSetting := model.Properties.FeatureSettings; featureSetting != nil {
if pointer.From(featureSetting.CrossRegionRestoreSettings.State) == backupvaults.CrossRegionRestoreStateEnabled {
crossRegionStoreEnabled = true
}
}
}

d.Set("cross_region_restore_enabled", crossRegionStoreEnabled)

if err = d.Set("identity", flattenBackupVaultDppIdentityDetails(model.Identity)); err != nil {
return fmt.Errorf("setting `identity`: %+v", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ func TestAccDataProtectionBackupVault_basic(t *testing.T) {
})
}

func TestAccDataProtectionBackupVault_crossRegionRestore(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_data_protection_backup_vault", "test")
r := DataProtectionBackupVaultResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.crossRegionRestore(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccDataProtectionBackupVault_zoneRedundant(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_data_protection_backup_vault", "test")
r := DataProtectionBackupVaultResource{}
Expand Down Expand Up @@ -178,6 +192,22 @@ resource "azurerm_data_protection_backup_vault" "test" {
`, template, data.RandomInteger)
}

func (r DataProtectionBackupVaultResource) crossRegionRestore(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s
resource "azurerm_data_protection_backup_vault" "test" {
name = "acctest-bv-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
datastore_type = "VaultStore"
redundancy = "GeoRedundant"
cross_region_restore_enabled = true
}
`, template, data.RandomInteger)
}

func (r DataProtectionBackupVaultResource) requiresImport(data acceptance.TestData) string {
config := r.basic(data)
return fmt.Sprintf(`
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/data_protection_backup_vault.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ The following arguments are supported:

* `redundancy` - (Required) Specifies the backup storage redundancy. Possible values are `GeoRedundant`, `LocallyRedundant` and `ZoneRedundant`. Changing this forces a new Backup Vault to be created.

* `cross_region_restore_enabled` - (Optional) Whether to enable cross-region restore for the Backup Vault.

-> **Note:** The `cross_region_restore_enabled` can only be specified when `redundancy` is specified for `GeoRedundant`. Once `cross_region_restore_enabled` is enabled, it cannot be disabled.

---

* `identity` - (Optional) An `identity` block as defined below.
Expand Down

0 comments on commit 252b9e5

Please sign in to comment.