With the release of AWS provider version 5.x, most attributes have been deprecated and new resources have been created regarding s3 buckets.
I have a module where I create an aws_s3_bucket resource and can create multiple aws-s3_bucket_lifecycle_configuration resources.
The issue I’m having is that for the lifecycle configuration itself, you can have multiple scenarios regarding the filter:
- empty filter without any prefix or tags
- a filter with a prefix, but no tags
- a filter with a tag, but no prefix
- multiple tags, no prefix
- prefix with multiple tags
- prefix with one tag
However, I’m having trouble with being able to handle all these different scenarios in my module because based on the above mentioned scenario, there could be a need for additional configuration blocks and based on which scenario you run into, you could have the filter wrapped in different configuration blocks.
Any guidance would be helpful in how to handle this new resource.
EXAMPLE CODE:
main.tf
resource "aws_s3_bucket" "bucket" {
count = !var.ignore-lifecycle-rule-changes ? 1 : 0
bucket = var.bucket-name
tags = merge({ "Name" = var.bucket-name }, var.bucket-tags)
}
resource "aws_s3_bucket_lifecycle_configuration" "bucket_lifecycle_config" {
bucket = !var.ignore-lifecycle-rule-changes ? aws_s3_bucket.bucket[0].id : aws_s3_bucket.bucket-ignored-lifecycle[0].id
for_each = { for rule in var.lifecycle-rules : rule.id => rule }
rule {
id = each.value.id
status = each.value.status
filter {
and {
prefix = each.value.prefix
tags = each.value.tags
}
}
abort_incomplete_multipart_upload {
days_after_initiation = each.value.abort_incomplete_multipart_upload_days
}
dynamic "expiration" {
for_each = each.value.expiration != null ? [each.value.expiration] : []
iterator = expr
content {
date = expr.value.date
days = expr.value.days
expired_object_delete_marker = expr.value.expired_object_delete_marker
}
}
dynamic "noncurrent_version_expiration" {
for_each = each.value.noncurrent_version_expiration != null ? [each.value.noncurrent_version_expiration] : []
iterator = transition
content {
noncurrent_days = transition.value.days
newer_noncurrent_versions = transition.value.versions
}
}
dynamic "transition" {
for_each = each.value.transition != null ? [each.value.transition] : []
iterator = transition
content {
date = transition.value.date
days = transition.value.days
storage_class = transition.value.storage_class
}
}
dynamic "noncurrent_version_transition" {
for_each = each.value.noncurrent_version_transition != null ? [each.value.noncurrent_version_transition] : []
iterator = transition
content {
noncurrent_days = transition.value.days
newer_noncurrent_versions = transition.value.versions
storage_class = transition.value.storage_class
}
}
}
}
variables.tf
variable "bucket-name" {
description = ""
type = string
}
variable "ignore-lifecycle-rule-changes" {
description = "Used when lifecycle rules are managed outside of Terraform"
type = bool
default = false
}
variable "lifecycle-rules" {
description = ""
default = []
type = list(object({
id = string
prefix = string
tags = map(string)
status = string
abort_incomplete_multipart_upload_days = number
expiration = object({
date = string
days = number
expired_object_delete_marker = bool
})
noncurrent_version_expiration = object({
days = number
versions = number
})
transition = object({
date = string
days = number
storage_class = string
})
noncurrent_version_transition = object({
versions = number
days = number
storage_class = string
})
}))
}
variable "bucket-tags" {
description = ""
type = map(string)
default = {}
}