From e9da67bf00b2c7609b0355bf928957cc2bed3d22 Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Tue, 2 Jan 2024 14:47:48 -0800 Subject: [PATCH 1/2] Allow specifying an archival policy for buckets Only enables this for openscapes, which is using it as described in https://github.com/2i2c-org/infrastructure/issues/3562. --- docs/howto/features/buckets.md | 9 +++++++++ terraform/aws/buckets.tf | 12 ++++++++++++ terraform/aws/projects/openscapes.tfvars | 3 +++ terraform/aws/variables.tf | 17 +++++++++++++---- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/howto/features/buckets.md b/docs/howto/features/buckets.md index a94f36e14..c7150fb67 100644 --- a/docs/howto/features/buckets.md +++ b/docs/howto/features/buckets.md @@ -15,6 +15,9 @@ on why users want this! }, "bucket2": { "delete_after": null + }, + "bucket3": { + "archival_storageclass_after": 3 } } ``` @@ -28,6 +31,12 @@ on why users want this! very helpful for 'scratch' buckets that are temporary. Set to `null` to prevent this cleaning up process from happening, e.g., if users want a persistent bucket. + `archival_storageclass_after` (available only for AWS currently) transitions objects + created in this bucket to a cheaper, slower archival class after the number of days + specified in this variable. This is helpful for archiving user home directories or similar + use cases, where data needs to be kept for a long time but rarely accessed. This should + not be used for frequently accessed or publicly accessible data. + 2. Enable access to these buckets from the hub or make them publicly accessible from outside by [editing `hub_cloud_permissions`](howto:features:cloud-access:access-perms) in the same `.tfvars` file. Follow all the steps listed there - this diff --git a/terraform/aws/buckets.tf b/terraform/aws/buckets.tf index 195a5083e..b1f77afb2 100644 --- a/terraform/aws/buckets.tf +++ b/terraform/aws/buckets.tf @@ -16,6 +16,18 @@ resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" { days = each.value.delete_after } } + + rule { + id = "archival-storageclass" + status = each.value.delete_after != null ? "Enabled" : "Disabled" + + transition { + # Transition this to much cheaper object storage after a few days + days = each.value.archival_storageclass_after + # Glacier Instant is fast enough while also being pretty cheap + storage_class = "GLACIER_IR" + } + } } locals { diff --git a/terraform/aws/projects/openscapes.tfvars b/terraform/aws/projects/openscapes.tfvars index 27c2207d8..80a1e287b 100644 --- a/terraform/aws/projects/openscapes.tfvars +++ b/terraform/aws/projects/openscapes.tfvars @@ -11,6 +11,9 @@ user_buckets = { "scratch" : { "delete_after" : 7 }, + "prod-homedirs-archive" : { + "archival_storageclass_after" : 3 + } } diff --git a/terraform/aws/variables.tf b/terraform/aws/variables.tf index 7e2f27bd1..281374d1b 100644 --- a/terraform/aws/variables.tf +++ b/terraform/aws/variables.tf @@ -20,7 +20,12 @@ variable "cluster_nodes_location" { } variable "user_buckets" { - type = map(object({ delete_after : number })) + type = map( + object({ + delete_after : optional(number, null), + archival_storageclass_after : optional(number, null) + }) + ) default = {} description = <<-EOT S3 Buckets to be created. @@ -28,9 +33,13 @@ variable "user_buckets" { The key for each entry will be prefixed with {var.prefix}- to form the name of the bucket. - The value is a map, with 'delete_after' the only accepted key in that - map - it lists the number of days after which any content in the - bucket will be deleted. Set to null to not delete data. + The value is a map, with the following accepted keys: + + 1. `delete_after` - number of days after *creation* an object in this + bucket will be automatically deleted. Set to null to not delete data. + 2. `archival_storageclass_after` - number of days after *creation* an + object in this bucket will be automatically transitioned to a cheaper, + slower storageclass for cost savings. Set to null to not transition. EOT } From 95443afe6f479721b3b524f8d580390d24d50e84 Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Mon, 15 Jan 2024 20:30:24 -0800 Subject: [PATCH 2/2] Don't apply archival storageclass rule unless necessary --- terraform/aws/buckets.tf | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/terraform/aws/buckets.tf b/terraform/aws/buckets.tf index b1f77afb2..2b1c7244d 100644 --- a/terraform/aws/buckets.tf +++ b/terraform/aws/buckets.tf @@ -17,15 +17,21 @@ resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" { } } - rule { - id = "archival-storageclass" - status = each.value.delete_after != null ? "Enabled" : "Disabled" + dynamic "rule" { + # Only set up this rule if it will be enabled. Prevents unnecessary + # churn in terraform + for_each = each.value.archival_storageclass_after != null ? [1] : [] - transition { - # Transition this to much cheaper object storage after a few days - days = each.value.archival_storageclass_after - # Glacier Instant is fast enough while also being pretty cheap - storage_class = "GLACIER_IR" + content { + id = "archival-storageclass" + status = "Enabled" + + transition { + # Transition this to much cheaper object storage after a few days + days = each.value.archival_storageclass_after + # Glacier Instant is fast enough while also being pretty cheap + storage_class = "GLACIER_IR" + } } } }