From 4793dd22f0fa75ff5f27221971ee2af7317d805e Mon Sep 17 00:00:00 2001 From: Alexis BRENON Date: Mon, 12 Sep 2022 19:00:03 +0200 Subject: [PATCH] feat: Add var to define different lifecycle rules for each bucket (#169) --- README.md | 1 + examples/multiple_buckets/main.tf | 11 +++++++++ main.tf | 2 +- .../multiple_buckets/multiple_buckets_test.go | 5 ++++ variables.tf | 23 +++++++++++++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 49249ee1..4688b14c 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Functional examples are included in the | bucket\_admins | Map of lowercase unprefixed name => comma-delimited IAM-style per-bucket admins. | `map(string)` | `{}` | no | | bucket\_creators | Map of lowercase unprefixed name => comma-delimited IAM-style per-bucket creators. | `map(string)` | `{}` | no | | bucket\_hmac\_key\_admins | Map of lowercase unprefixed name => comma-delimited IAM-style per-bucket HMAC Key admins. | `map(string)` | `{}` | no | +| bucket\_lifecycle\_rules | Additionnal lifecycle\_rules for specific buckets. Map of lowercase unprefixed name => list of lifecycle rules to configure. |
map(set(object({
# Object with keys:
# - type - The type of the action of this Lifecycle Rule. Supported values: Delete and SetStorageClass.
# - storage_class - (Required if action type is SetStorageClass) The target Storage Class of objects affected by this Lifecycle Rule.
action = map(string)

# Object with keys:
# - age - (Optional) Minimum age of an object in days to satisfy this condition.
# - created_before - (Optional) Creation date of an object in RFC 3339 (e.g. 2017-06-13) to satisfy this condition.
# - with_state - (Optional) Match to live and/or archived objects. Supported values include: "LIVE", "ARCHIVED", "ANY".
# - matches_storage_class - (Optional) Comma delimited string for storage class of objects to satisfy this condition. Supported values include: MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, DURABLE_REDUCED_AVAILABILITY.
# - num_newer_versions - (Optional) Relevant only for versioned objects. The number of newer versions of an object to satisfy this condition.
# - custom_time_before - (Optional) A date in the RFC 3339 format YYYY-MM-DD. This condition is satisfied when the customTime metadata for the object is set to an earlier date than the date used in this lifecycle condition.
# - days_since_custom_time - (Optional) The number of days from the Custom-Time metadata attribute after which this condition becomes true.
# - days_since_noncurrent_time - (Optional) Relevant only for versioned objects. Number of days elapsed since the noncurrent timestamp of an object.
# - noncurrent_time_before - (Optional) Relevant only for versioned objects. The date in RFC 3339 (e.g. 2017-06-13) when the object became nonconcurrent.
condition = map(string)
})))
| `{}` | no | | bucket\_policy\_only | Disable ad-hoc ACLs on specified buckets. Defaults to true. Map of lowercase unprefixed name => boolean | `map(bool)` | `{}` | no | | bucket\_storage\_admins | Map of lowercase unprefixed name => comma-delimited IAM-style per-bucket storage admins. | `map(string)` | `{}` | no | | bucket\_viewers | Map of lowercase unprefixed name => comma-delimited IAM-style per-bucket viewers. | `map(string)` | `{}` | no | diff --git a/examples/multiple_buckets/main.tf b/examples/multiple_buckets/main.tf index 17ed516e..2b3edc7f 100644 --- a/examples/multiple_buckets/main.tf +++ b/examples/multiple_buckets/main.tf @@ -45,6 +45,17 @@ module "cloud_storage" { } }] + bucket_lifecycle_rules = { + "one" = [{ + action = { + type = "Delete" + } + condition = { + age = "90" + } + }] + } + default_event_based_hold = { "one" = true } diff --git a/main.tf b/main.tf index a9920d73..7ca5c82c 100644 --- a/main.tf +++ b/main.tf @@ -110,7 +110,7 @@ resource "google_storage_bucket" "buckets" { } dynamic "lifecycle_rule" { - for_each = var.lifecycle_rules + for_each = setunion(var.lifecycle_rules, lookup(var.bucket_lifecycle_rules, each.value, toset([]))) content { action { type = lifecycle_rule.value.action.type diff --git a/test/integration/multiple_buckets/multiple_buckets_test.go b/test/integration/multiple_buckets/multiple_buckets_test.go index 7a0af318..d2111b80 100644 --- a/test/integration/multiple_buckets/multiple_buckets_test.go +++ b/test/integration/multiple_buckets/multiple_buckets_test.go @@ -52,12 +52,17 @@ func TestMultipleBuckets(t *testing.T) { // bucket with suffix one assert.True(op.Get("metadata.iamConfiguration.bucketPolicyOnly.enabled").Bool(), "bucketPolicyOnly is enabled") assert.True(op.Get("metadata.defaultEventBasedHold").Bool(), "defaultEventBasedHold is enabled") + bucket_lifecycle := op.Get("metadata.lifecycle.rule").Array()[1] + assert.Equal("Delete", bucket_lifecycle.Get("action.type").String(), "bucket lifecycle action is Delete") + assert.Equal("90", bucket_lifecycle.Get("condition.age").String(), "bucket lifecycle condition is age 90") case "two": // bucket with suffix two assert.False(op.Get("metadata.iamConfiguration.bucketPolicyOnly.enabled").Bool(), "bucketPolicyOnly is disabled") assert.False(op.Get("metadata.defaultEventBasedHold").Bool(), "defaultEventBasedHold is disabled") gcloud.Run(t, fmt.Sprintf("alpha storage ls --buckets gs://%s/dev/", bucketName), gcloudArgs) gcloud.Run(t, fmt.Sprintf("alpha storage ls --buckets gs://%s/prod/", bucketName), gcloudArgs) + bucket_lifecycles := op.Get("metadata.lifecycle.rule").Array() + assert.Equal(1, len(bucket_lifecycles), "Bucket 'two' has 1 lifecycle rule") default: // fail test if unknown suffix t.Fatalf("Only expected two buckets with suffixes one and two. Found: %s", bucketName) diff --git a/variables.tf b/variables.tf index f0185a3f..a4ce6b64 100644 --- a/variables.tf +++ b/variables.tf @@ -204,6 +204,29 @@ variable "lifecycle_rules" { default = [] } +variable "bucket_lifecycle_rules" { + type = map(set(object({ + # Object with keys: + # - type - The type of the action of this Lifecycle Rule. Supported values: Delete and SetStorageClass. + # - storage_class - (Required if action type is SetStorageClass) The target Storage Class of objects affected by this Lifecycle Rule. + action = map(string) + + # Object with keys: + # - age - (Optional) Minimum age of an object in days to satisfy this condition. + # - created_before - (Optional) Creation date of an object in RFC 3339 (e.g. 2017-06-13) to satisfy this condition. + # - with_state - (Optional) Match to live and/or archived objects. Supported values include: "LIVE", "ARCHIVED", "ANY". + # - matches_storage_class - (Optional) Comma delimited string for storage class of objects to satisfy this condition. Supported values include: MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, DURABLE_REDUCED_AVAILABILITY. + # - num_newer_versions - (Optional) Relevant only for versioned objects. The number of newer versions of an object to satisfy this condition. + # - custom_time_before - (Optional) A date in the RFC 3339 format YYYY-MM-DD. This condition is satisfied when the customTime metadata for the object is set to an earlier date than the date used in this lifecycle condition. + # - days_since_custom_time - (Optional) The number of days from the Custom-Time metadata attribute after which this condition becomes true. + # - days_since_noncurrent_time - (Optional) Relevant only for versioned objects. Number of days elapsed since the noncurrent timestamp of an object. + # - noncurrent_time_before - (Optional) Relevant only for versioned objects. The date in RFC 3339 (e.g. 2017-06-13) when the object became nonconcurrent. + condition = map(string) + }))) + description = "Additionnal lifecycle_rules for specific buckets. Map of lowercase unprefixed name => list of lifecycle rules to configure." + default = {} +} + variable "cors" { description = "Set of maps of mixed type attributes for CORS values. See appropriate attribute types here: https://www.terraform.io/docs/providers/google/r/storage_bucket.html#cors" type = set(any)