Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_storage_account: add permanent_delete_enabled #25778

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 67 additions & 4 deletions internal/services/storage/storage_account_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,11 @@ func resourceStorageAccount() *pluginsdk.Resource {
Default: 7,
ValidateFunc: validation.IntBetween(1, 365),
},
"permanent_delete_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: false,
},
},
},
},
Expand Down Expand Up @@ -1932,6 +1937,20 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e
return fmt.Errorf("`versioning_enabled` can't be true when `is_hns_enabled` is true")
}

// Disable restore_policy first. Disabling restore_policy and while setting delete_retention_policy.allow_permanent_delete to true cause error.
// Issue : https://github.com/Azure/azure-rest-api-specs/issues/11237
if v := d.Get("blob_properties.0.restore_policy"); d.HasChange("blob_properties.0.restore_policy") && len(v.([]interface{})) == 0 {
log.Print("[DEBUG] Disabling RestorePolicy prior to changing DeleteRetentionPolicy")
props := storage.BlobServiceProperties{
BlobServicePropertiesProperties: &storage.BlobServicePropertiesProperties{
RestorePolicy: expandBlobPropertiesRestorePolicy(v.([]interface{})),
},
}
if _, err := blobClient.SetServiceProperties(ctx, id.ResourceGroupName, id.StorageAccountName, props); err != nil {
return fmt.Errorf("updating Azure Storage Account blob restore policy %q: %+v", id.StorageAccountName, err)
}
}

if d.Get("dns_endpoint_type").(string) == string(storage.DNSEndpointTypeAzureDNSZone) {
if blobProperties.RestorePolicy != nil && blobProperties.RestorePolicy.Enabled != nil && *blobProperties.RestorePolicy.Enabled {
// Otherwise, API returns: "Required feature Global Dns is disabled"
Expand Down Expand Up @@ -2786,7 +2805,7 @@ func expandBlobProperties(kind storage.Kind, input []interface{}) (*storage.Blob
props.BlobServicePropertiesProperties.DeleteRetentionPolicy = expandBlobPropertiesDeleteRetentionPolicy(deletePolicyRaw)

containerDeletePolicyRaw := v["container_delete_retention_policy"].([]interface{})
props.BlobServicePropertiesProperties.ContainerDeleteRetentionPolicy = expandBlobPropertiesDeleteRetentionPolicy(containerDeletePolicyRaw)
props.BlobServicePropertiesProperties.ContainerDeleteRetentionPolicy = expandBlobPropertiesContainerDeleteRetentionPolicyWithoutPermDeleteOption(containerDeletePolicyRaw)

corsRaw := v["cors_rule"].([]interface{})
props.BlobServicePropertiesProperties.Cors = expandBlobPropertiesCors(corsRaw)
Expand Down Expand Up @@ -2861,6 +2880,23 @@ func expandBlobPropertiesDeleteRetentionPolicy(input []interface{}) *storage.Del

policy := input[0].(map[string]interface{})

return &storage.DeleteRetentionPolicy{
Enabled: utils.Bool(true),
Days: utils.Int32(int32(policy["days"].(int))),
AllowPermanentDelete: utils.Bool(policy["permanent_delete_enabled"].(bool)),
}
}

func expandBlobPropertiesContainerDeleteRetentionPolicyWithoutPermDeleteOption(input []interface{}) *storage.DeleteRetentionPolicy {
result := storage.DeleteRetentionPolicy{
Enabled: utils.Bool(false),
}
if len(input) == 0 || input[0] == nil {
return &result
}

policy := input[0].(map[string]interface{})

return &storage.DeleteRetentionPolicy{
Enabled: utils.Bool(true),
Days: utils.Int32(int32(policy["days"].(int))),
Expand Down Expand Up @@ -2933,7 +2969,7 @@ func expandShareProperties(input []interface{}) storage.FileServiceProperties {

v := input[0].(map[string]interface{})

props.FileServicePropertiesProperties.ShareDeleteRetentionPolicy = expandBlobPropertiesDeleteRetentionPolicy(v["retention_policy"].([]interface{}))
props.FileServicePropertiesProperties.ShareDeleteRetentionPolicy = expandBlobPropertiesContainerDeleteRetentionPolicyWithoutPermDeleteOption(v["retention_policy"].([]interface{}))

props.FileServicePropertiesProperties.Cors = expandBlobPropertiesCors(v["cors_rule"].([]interface{}))

Expand Down Expand Up @@ -3319,7 +3355,7 @@ func flattenBlobProperties(input storage.BlobServiceProperties) []interface{} {

flattenedContainerDeletePolicy := make([]interface{}, 0)
if containerDeletePolicy := input.BlobServicePropertiesProperties.ContainerDeleteRetentionPolicy; containerDeletePolicy != nil {
flattenedContainerDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicy(containerDeletePolicy)
flattenedContainerDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicyWithoutPermDeleteOption(containerDeletePolicy)
}

versioning, changeFeedEnabled, changeFeedRetentionInDays := false, false, 0
Expand Down Expand Up @@ -3413,6 +3449,33 @@ func flattenBlobPropertiesDeleteRetentionPolicy(input *storage.DeleteRetentionPo
return deleteRetentionPolicy
}

if enabled := input.Enabled; enabled != nil && *enabled {
days := 0
if input.Days != nil {
days = int(*input.Days)
}

var permanentDeleteEnabled bool
if input.AllowPermanentDelete != nil {
permanentDeleteEnabled = *input.AllowPermanentDelete
}

deleteRetentionPolicy = append(deleteRetentionPolicy, map[string]interface{}{
"days": days,
"permanent_delete_enabled": permanentDeleteEnabled,
})
}

return deleteRetentionPolicy
}

func flattenBlobPropertiesDeleteRetentionPolicyWithoutPermDeleteOption(input *storage.DeleteRetentionPolicy) []interface{} {
deleteRetentionPolicy := make([]interface{}, 0)

if input == nil {
return deleteRetentionPolicy
}

if enabled := input.Enabled; enabled != nil && *enabled {
days := 0
if input.Days != nil {
Expand Down Expand Up @@ -3560,7 +3623,7 @@ func flattenShareProperties(input storage.FileServiceProperties) []interface{} {

flattenedDeletePolicy := make([]interface{}, 0)
if deletePolicy := input.FileServicePropertiesProperties.ShareDeleteRetentionPolicy; deletePolicy != nil {
flattenedDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicy(deletePolicy)
flattenedDeletePolicy = flattenBlobPropertiesDeleteRetentionPolicyWithoutPermDeleteOption(deletePolicy)
}

flattenedSMB := make([]interface{}, 0)
Expand Down
2 changes: 2 additions & 0 deletions internal/services/storage/storage_account_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ func TestAccStorageAccount_blobProperties(t *testing.T) {
check.That(data.ResourceName).Key("blob_properties.0.delete_retention_policy.0.days").HasValue("7"),
check.That(data.ResourceName).Key("blob_properties.0.versioning_enabled").HasValue("false"),
check.That(data.ResourceName).Key("blob_properties.0.change_feed_enabled").HasValue("false"),
check.That(data.ResourceName).Key("blob_properties.0.delete_retention_policy.0.permanent_delete_enabled").HasValue("true"),
),
},
data.ImportStep(),
Expand Down Expand Up @@ -2778,6 +2779,7 @@ resource "azurerm_storage_account" "test" {
}

delete_retention_policy {
permanent_delete_enabled = true
}

container_delete_retention_policy {
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/storage_account.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ A `delete_retention_policy` block supports the following:

* `days` - (Optional) Specifies the number of days that the blob should be retained, between `1` and `365` days. Defaults to `7`.

* `permanent_delete_enabled` - (Optional) Indicates whether permanent deletion of the soft deleted blob versions and snapshots is allowed. Defaults to `false`.

~> **NOTE:** `permanent_delete_enabled` cannot be set to true if a `restore_policy` block is defined.

---

A `restore_policy` block supports the following:
Expand Down
Loading