From 2ffb4fa3559854017ca8f10f8174d0f3d3e566c0 Mon Sep 17 00:00:00 2001
From: Timo Hajati <20628630+hajati@users.noreply.github.com>
Date: Wed, 24 Jan 2024 09:31:31 +0100
Subject: [PATCH] Allows S3 Lifecycle for RDS Dump Bucket
---
README.md | 26 ++++++++++++++++++++++
examples/rds/main.tf | 30 ++++++++++++++++++++++++++
rds-s3-dumps.tf | 38 +++++++++++++++++++++++++++++++++
variables.tf | 51 ++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 143 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 1e62621..78bb4f5 100644
--- a/README.md
+++ b/README.md
@@ -1312,6 +1312,32 @@ Type: `string`
Default: `""`
+### [rds\_s3\_dump\_lifecycle\_rules](#input\_rds\_s3\_dump\_lifecycle\_rules)
+
+Description: RDS S3 Dump Lifecycle rules
+
+Type:
+
+```hcl
+list(object({
+ id = string
+ status = optional(string, "Enabled")
+ prefix = string
+ expiration = optional(list(object({
+ days = optional(number)
+ date = optional(string)
+ expired_object_delete_marker = optional(bool)
+ })), [])
+ transition = optional(list(object({
+ days = optional(number)
+ date = optional(string)
+ storage_class = string
+ })), [])
+ }))
+```
+
+Default: `[]`
+
### [rds\_identifier\_override](#input\_rds\_identifier\_override)
Description: RDS identifier override. Use only lowercase, numbers and -, \_., only use when it needs to be different from var.name
diff --git a/examples/rds/main.tf b/examples/rds/main.tf
index b44bdc7..a9080f2 100644
--- a/examples/rds/main.tf
+++ b/examples/rds/main.tf
@@ -20,6 +20,36 @@ module "ms_sample_rds" {
# rds_enabled enables RDS
rds_enabled = true
+ rds_s3_dump_lifecycle_rules = [
+ {
+ id = "all-cleanup"
+ status = "Enabled"
+ prefix = ""
+ expiration = [{
+ days = 90
+ }]
+ },
+ {
+ id = "tmp"
+ status = "Enabled"
+ prefix = "tmp/"
+ expiration = [{
+ days = 1
+ }]
+ },
+ {
+ id = "MoveAllToGlacierAfterTwoWeeks"
+ status = "Enabled"
+ prefix = ""
+ transition = [
+ {
+ days = 28
+ storage_class = "GLACIER"
+ }
+ ]
+ }
+ ]
+
# rds_allowed_subnet_cidrs specifices the allowed subnets
#rds_allowed_subnet_cidrs = ["127.0.0.1/32"]
diff --git a/rds-s3-dumps.tf b/rds-s3-dumps.tf
index f013e88..d8bd946 100644
--- a/rds-s3-dumps.tf
+++ b/rds-s3-dumps.tf
@@ -182,3 +182,41 @@ resource "aws_db_instance_role_association" "this" {
feature_name = "S3_INTEGRATION"
role_arn = var.rds_s3_dump_role_arn == "" ? aws_iam_role.rds_dumps[0].arn : var.rds_s3_dump_role_arn
}
+
+resource "aws_s3_bucket_lifecycle_configuration" "rds_dumps" {
+ depends_on = [aws_s3_bucket_versioning.rds_dumps]
+
+ count = local.rds_dumps_enabled && length(var.rds_s3_dump_lifecycle_rules) > 0 ? 1 : 0
+ bucket = aws_s3_bucket.rds_dumps[count.index].id
+
+ dynamic "rule" {
+ for_each = var.rds_s3_dump_lifecycle_rules
+
+ content {
+ id = rule.value.id
+ status = rule.value.status
+ filter {
+ prefix = rule.value.prefix
+ }
+
+ dynamic "expiration" {
+ for_each = rule.value.expiration
+
+ content {
+ date = expiration.value.date
+ days = expiration.value.days
+ expired_object_delete_marker = expiration.value.expired_object_delete_marker
+ }
+ }
+
+ dynamic "transition" {
+ for_each = rule.value.transition
+ content {
+ date = transition.value.date
+ days = transition.value.days
+ storage_class = transition.value.storage_class
+ }
+ }
+ }
+ }
+}
diff --git a/variables.tf b/variables.tf
index d084f7f..fd412d8 100644
--- a/variables.tf
+++ b/variables.tf
@@ -787,6 +787,51 @@ variable "rds_s3_dump_role_arn" {
default = ""
}
+variable "rds_s3_dump_lifecycle_rules" {
+ description = "RDS S3 Dump Lifecycle rules"
+ default = []
+ type = list(object({
+ id = string
+ status = optional(string, "Enabled")
+ prefix = string
+ expiration = optional(list(object({
+ days = optional(number)
+ date = optional(string)
+ expired_object_delete_marker = optional(bool)
+ })), [])
+ transition = optional(list(object({
+ days = optional(number)
+ date = optional(string)
+ storage_class = string
+ })), [])
+ }))
+
+ validation {
+ condition = length(var.rds_s3_dump_lifecycle_rules) > 0 ? alltrue([
+ for k, v in var.rds_s3_dump_lifecycle_rules : (length(v["expiration"]) <= 1)
+ ]) : true
+ error_message = "Only one `expiration` block is allowed."
+ }
+
+ validation {
+ condition = length(var.rds_s3_dump_lifecycle_rules) > 0 ? alltrue(flatten([
+ for k, v in var.rds_s3_dump_lifecycle_rules : [
+ for bk, bv in v["expiration"] : (bv["days"] == null || bv["date"] == null)
+ ]
+ ])) : true
+ error_message = "Either `days` or `date` value should be set for `expiration`, but not both."
+ }
+
+ validation {
+ condition = length(var.rds_s3_dump_lifecycle_rules) > 0 ? alltrue(flatten([
+ for k, v in var.rds_s3_dump_lifecycle_rules : [
+ for bk, bv in v["transition"] : (bv["days"] == null || bv["date"] == null)
+ ]
+ ])) : true
+ error_message = "Either `days` or `date` value should be set for `transition`, but not both."
+ }
+}
+
variable "rds_identifier_override" {
description = "RDS identifier override. Use only lowercase, numbers and -, _., only use when it needs to be different from var.name"
default = ""
@@ -1164,7 +1209,8 @@ variable "s3_lifecycle_rules" {
condition = length(var.s3_lifecycle_rules) > 0 ? alltrue(flatten([
for k, v in var.s3_lifecycle_rules : [
for bk, bv in v["expiration"] : (bv["days"] == null || bv["date"] == null)
- ]])) : true
+ ]
+ ])) : true
error_message = "Either `days` or `date` value should be set for `expiration`, but not both."
}
@@ -1172,7 +1218,8 @@ variable "s3_lifecycle_rules" {
condition = length(var.s3_lifecycle_rules) > 0 ? alltrue(flatten([
for k, v in var.s3_lifecycle_rules : [
for bk, bv in v["transition"] : (bv["days"] == null || bv["date"] == null)
- ]])) : true
+ ]
+ ])) : true
error_message = "Either `days` or `date` value should be set for `transition`, but not both."
}
}