diff --git a/postgres_flexible_server/tests/resources.tf b/postgres_flexible_server/tests/resources.tf index 6a3dfeae..513927e5 100644 --- a/postgres_flexible_server/tests/resources.tf +++ b/postgres_flexible_server/tests/resources.tf @@ -221,7 +221,10 @@ module "storage_account" { blob_delete_retention_days = 7 blob_change_feed_enabled = true blob_change_feed_retention_in_days = 10 - blob_restore_policy_days = 6 + blob_storage_policy = { + blob_restore_policy_days = 6 + enable_immutability_policy = false + } tags = var.tags } diff --git a/storage_account/README.md b/storage_account/README.md index b23dae66..8ea3e8b9 100644 --- a/storage_account/README.md +++ b/storage_account/README.md @@ -90,6 +90,10 @@ resource "azurerm_private_dns_zone" "storage_account" { ``` +## Known Issues + +- Applying the immutability policy on an existing storage account fails due to a 404 NotFound error on the threat protection creation for the new storage. Solution, delete the resource and create the new one with the immutability policy. +- Changing the `period_since_creation_in_days` will be updated in terraform state but not in the cloud provider resource. Solution, change the value using the Azure portal. ## Migration from v2 @@ -202,6 +206,7 @@ No modules. | [azurerm_advanced_threat_protection.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/advanced_threat_protection) | resource | | [azurerm_monitor_metric_alert.storage_account_low_availability](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_metric_alert) | resource | | [azurerm_storage_account.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource | +| [null_resource.immutability](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | ## Inputs @@ -218,7 +223,7 @@ No modules. | [blob\_change\_feed\_retention\_in\_days](#input\_blob\_change\_feed\_retention\_in\_days) | (Optional) The duration of change feed events retention in days. The possible values are between 1 and 146000 days (400 years). Setting this to null (or omit this in the configuration file) indicates an infinite retention of the change feed. | `number` | `null` | no | | [blob\_container\_delete\_retention\_days](#input\_blob\_container\_delete\_retention\_days) | Retention days for deleted container. Valid value is between 1 and 365 (set to 0 to disable). | `number` | `0` | no | | [blob\_delete\_retention\_days](#input\_blob\_delete\_retention\_days) | Retention days for deleted blob. Valid value is between 1 and 365 (set to 0 to disable). | `number` | `0` | no | -| [blob\_restore\_policy\_days](#input\_blob\_restore\_policy\_days) | (Optional) Specifies the number of days that the blob can be restored, between 1 and 365 days. This must be less than the days specified for delete\_retention\_policy. | `number` | `0` | no | +| [blob\_storage\_policy](#input\_blob\_storage\_policy) | Handle immutability policy for stored elements |
object({
enable_immutability_policy = bool
blob_restore_policy_days = number
})
|
{
"blob_restore_policy_days": 0,
"enable_immutability_policy": false
}
| no | | [blob\_versioning\_enabled](#input\_blob\_versioning\_enabled) | Controls whether blob object versioning is enabled. | `bool` | `false` | no | | [cross\_tenant\_replication\_enabled](#input\_cross\_tenant\_replication\_enabled) | (Optional) Should cross Tenant replication be enabled? Defaults to false. | `bool` | `false` | no | | [custom\_domain](#input\_custom\_domain) | Custom domain for accessing blob data |
object({
name = string
use_subdomain = bool
})
|
{
"name": null,
"use_subdomain": false
}
| no | @@ -226,6 +231,7 @@ No modules. | [enable\_identity](#input\_enable\_identity) | (Optional) If true, set the identity as SystemAssigned | `bool` | `false` | no | | [enable\_low\_availability\_alert](#input\_enable\_low\_availability\_alert) | Enable the Low Availability alert. Default is true | `bool` | `true` | no | | [error\_404\_document](#input\_error\_404\_document) | The absolute path to a custom webpage that should be used when a request is made which does not correspond to an existing file. | `string` | `null` | no | +| [immutability\_policy\_props](#input\_immutability\_policy\_props) | Properties to setup the immutability policy. The resource can be created only with "Disabled" and "Unlocked" state. Change to "Locked" state doens't update the resource for a bug of the current module. |
object({
allow_protected_append_writes = bool
period_since_creation_in_days = number
})
|
{
"allow_protected_append_writes": false,
"period_since_creation_in_days": 730
}
| no | | [index\_document](#input\_index\_document) | The webpage that Azure Storage serves for requests to the root of a website or any subfolder. For example, index.html. The value is case-sensitive. | `string` | `null` | no | | [is\_hns\_enabled](#input\_is\_hns\_enabled) | Enable Hierarchical Namespace enabled (Azure Data Lake Storage Gen 2). Changing this forces a new resource to be created. | `bool` | `false` | no | | [is\_sftp\_enabled](#input\_is\_sftp\_enabled) | Enable SFTP | `bool` | `false` | no | diff --git a/storage_account/main.tf b/storage_account/main.tf index 32b66800..301f315b 100644 --- a/storage_account/main.tf +++ b/storage_account/main.tf @@ -37,9 +37,9 @@ resource "azurerm_storage_account" "this" { } dynamic "restore_policy" { - for_each = (var.blob_restore_policy_days == 0 ? [] : [1]) + for_each = (var.blob_storage_policy.blob_restore_policy_days == 0 ? [] : [1]) content { - days = var.blob_restore_policy_days + days = var.blob_storage_policy.blob_restore_policy_days } } } @@ -81,10 +81,22 @@ resource "azurerm_storage_account" "this" { } } + dynamic "immutability_policy" { + for_each = var.blob_storage_policy.enable_immutability_policy ? [1] : [] + + content { + allow_protected_append_writes = var.immutability_policy_props.allow_protected_append_writes + state = "Unlocked" + period_since_creation_in_days = var.immutability_policy_props.period_since_creation_in_days + } + } + # the use of storage_account_customer_managed_key resource will cause a bug on the plan: this paramenter will always see as changed. + # the state property is ignored because is overridden from a null_resource. lifecycle { ignore_changes = [ - customer_managed_key + customer_managed_key, + immutability_policy.0.state ] } @@ -134,3 +146,28 @@ resource "azurerm_monitor_metric_alert" "storage_account_low_availability" { tags = var.tags } + +resource "null_resource" "immutability" { + + triggers = { + immutability_policy : var.blob_storage_policy.enable_immutability_policy + resouce_group_name : var.resource_group_name + name : var.name + } + + provisioner "local-exec" { + command = <