From 7833203d87d19c711082fc8a99027b43ab6c101f Mon Sep 17 00:00:00 2001 From: Simone Ruffilli Date: Thu, 11 Apr 2024 09:31:00 +0200 Subject: [PATCH] Add support for GCS soft-delete retention period (#2212) * Add support for GCS soft-delete retention period --- modules/gcs/README.md | 12 ++-- modules/gcs/main.tf | 57 +++++++++++-------- modules/gcs/variables.tf | 6 ++ .../gcs/examples/retention-logging.yaml | 8 ++- tests/modules/gcs/examples/simple.yaml | 9 ++- 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/modules/gcs/README.md b/modules/gcs/README.md index 539d82ce6..7200f9508 100644 --- a/modules/gcs/README.md +++ b/modules/gcs/README.md @@ -56,7 +56,7 @@ module "bucket" { # tftest modules=3 skip e2e ``` -### Example with retention policy and logging +### Example with retention policy, soft delete policy and logging ```hcl module "bucket" { @@ -68,6 +68,7 @@ module "bucket" { retention_period = 100 is_locked = true } + soft_delete_retention = 7776000 logging_config = { log_bucket = "log-bucket" log_object_prefix = null @@ -240,10 +241,11 @@ module "bucket" { | [public_access_prevention](variables.tf#L224) | Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint. | string | | null | | [requester_pays](variables.tf#L230) | Enables Requester Pays on a storage bucket. | bool | | null | | [retention_policy](variables.tf#L236) | Bucket retention policy. | object({…}) | | null | -| [storage_class](variables.tf#L245) | Bucket storage class. | string | | "MULTI_REGIONAL" | -| [uniform_bucket_level_access](variables.tf#L255) | Allow using object ACLs (false) or not (true, this is the recommended behavior) , defaults to true (which is the recommended practice, but not the behavior of storage API). | bool | | true | -| [versioning](variables.tf#L261) | Enable versioning, defaults to false. | bool | | false | -| [website](variables.tf#L267) | Bucket website. | object({…}) | | null | +| [soft_delete_retention](variables.tf#L245) | The duration in seconds that soft-deleted objects in the bucket will be retained and cannot be permanently deleted. Set to 0 to override the default and disable. | number | | null | +| [storage_class](variables.tf#L251) | Bucket storage class. | string | | "MULTI_REGIONAL" | +| [uniform_bucket_level_access](variables.tf#L261) | Allow using object ACLs (false) or not (true, this is the recommended behavior) , defaults to true (which is the recommended practice, but not the behavior of storage API). | bool | | true | +| [versioning](variables.tf#L267) | Enable versioning, defaults to false. | bool | | false | +| [website](variables.tf#L273) | Bucket website. | object({…}) | | null | ## Outputs diff --git a/modules/gcs/main.tf b/modules/gcs/main.tf index c19c7912e..a1824bba1 100644 --- a/modules/gcs/main.tf +++ b/modules/gcs/main.tf @@ -41,12 +41,21 @@ resource "google_storage_bucket" "bucket" { } } - dynamic "website" { - for_each = var.website == null ? [] : [""] + dynamic "cors" { + for_each = var.cors == null ? [] : [""] + content { + origin = var.cors.origin + method = var.cors.method + response_header = var.cors.response_header + max_age_seconds = max(3600, var.cors.max_age_seconds) + } + } + + dynamic "custom_placement_config" { + for_each = var.custom_placement_config == null ? [] : [""] content { - main_page_suffix = var.website.main_page_suffix - not_found_page = var.website.not_found_page + data_locations = var.custom_placement_config } } @@ -58,14 +67,6 @@ resource "google_storage_bucket" "bucket" { } } - dynamic "retention_policy" { - for_each = var.retention_policy == null ? [] : [""] - content { - retention_period = var.retention_policy.retention_period - is_locked = var.retention_policy.is_locked - } - } - dynamic "logging" { for_each = var.logging_config == null ? [] : [""] content { @@ -74,16 +75,6 @@ resource "google_storage_bucket" "bucket" { } } - dynamic "cors" { - for_each = var.cors == null ? [] : [""] - content { - origin = var.cors.origin - method = var.cors.method - response_header = var.cors.response_header - max_age_seconds = max(3600, var.cors.max_age_seconds) - } - } - dynamic "lifecycle_rule" { for_each = var.lifecycle_rules iterator = rule @@ -108,11 +99,27 @@ resource "google_storage_bucket" "bucket" { } } - dynamic "custom_placement_config" { - for_each = var.custom_placement_config == null ? [] : [""] + dynamic "retention_policy" { + for_each = var.retention_policy == null ? [] : [""] + content { + retention_period = var.retention_policy.retention_period + is_locked = var.retention_policy.is_locked + } + } + + dynamic "soft_delete_policy" { + for_each = var.soft_delete_retention == null ? [] : [""] + content { + retention_duration_seconds = var.soft_delete_retention + } + } + + dynamic "website" { + for_each = var.website == null ? [] : [""] content { - data_locations = var.custom_placement_config + main_page_suffix = var.website.main_page_suffix + not_found_page = var.website.not_found_page } } } diff --git a/modules/gcs/variables.tf b/modules/gcs/variables.tf index de8a6abd8..0dbb937da 100644 --- a/modules/gcs/variables.tf +++ b/modules/gcs/variables.tf @@ -242,6 +242,12 @@ variable "retention_policy" { default = null } +variable "soft_delete_retention" { + description = "The duration in seconds that soft-deleted objects in the bucket will be retained and cannot be permanently deleted. Set to 0 to override the default and disable." + type = number + default = null +} + variable "storage_class" { description = "Bucket storage class." type = string diff --git a/tests/modules/gcs/examples/retention-logging.yaml b/tests/modules/gcs/examples/retention-logging.yaml index f92c1a6a2..ebe3e70dc 100644 --- a/tests/modules/gcs/examples/retention-logging.yaml +++ b/tests/modules/gcs/examples/retention-logging.yaml @@ -15,12 +15,14 @@ values: module.bucket.google_storage_bucket.bucket: logging: - - log_bucket: log-bucket + - log_bucket: log-bucket name: test-my-bucket project: project-id + soft_delete_policy: + - retention_duration_seconds: 7776000 retention_policy: - - is_locked: true - retention_period: 100 + - is_locked: true + retention_period: 100 counts: google_storage_bucket: 1 diff --git a/tests/modules/gcs/examples/simple.yaml b/tests/modules/gcs/examples/simple.yaml index 66120499d..fe18f9238 100644 --- a/tests/modules/gcs/examples/simple.yaml +++ b/tests/modules/gcs/examples/simple.yaml @@ -14,7 +14,8 @@ values: module.bucket.google_storage_bucket.bucket: - autoclass: [] + autoclass: + - enabled: false cors: [] custom_placement_config: [] default_event_based_hold: null @@ -33,9 +34,7 @@ values: timeouts: null uniform_bucket_level_access: true versioning: - - enabled: true - autoclass: - - enabled: false + - enabled: true counts: - google_storage_bucket: 1 \ No newline at end of file + google_storage_bucket: 1