I have a s3 lifecycle rule that should delete the failed multipart upload after n number of days by using lifecycle rules. I want to use lookup
instead of try
resource "aws_s3_bucket_lifecycle_configuration" "default" {
count = length(var.lifecycle_rule) != 0 ? 1 : 0
bucket = aws_s3_bucket.bucket.bucket
dynamic "rule" {
for_each = try(jsondecode(var.lifecycle_rule), var.lifecycle_rule)
content {
id = lookup(rule.value, "id", "default")
status = lookup(rule.value, "status", "Enabled")
dynamic "abort_incomplete_multipart_upload" {
for_each = lookup(rule.value, "abort_incomplete_multipart_upload", null) != null ? [rule.value.abort_incomplete_multipart_upload] : []
content {
days_after_initiation = abort_incomplete_multipart_upload.value.days_after_initiation
}
}
}
}
}
When I try to use this module resource in my child module, it does not work
module "test" {
source = "./s3"
bucket_name = "test"
lifecycle_rule = [
{
expiration = {
days = 7
}
},
{
id = "abort-incomplete-multipart-upload-lifecyle-rule"
abort_incomplete_multipart_upload_days = {
days_after_initiation = 6
}
}
]
}
terraform plan gives me
rule {
id = "abort-incomplete-multipart-upload-lifecyle-rule"
status = "Enabled"
filter {
}
}
expected output:
rule {
id = "abort-incomplete-multipart-upload-lifecyle-rule"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 8
}
filter {
}
}
CodePudding user response:
Here's the code that works:
resource "aws_s3_bucket_lifecycle_configuration" "default" {
count = length(var.lifecycle_rule) != 0 ? 1 : 0
bucket = aws_s3_bucket.bucket.bucket
dynamic "rule" {
for_each = try(jsondecode(var.lifecycle_rule), var.lifecycle_rule)
content {
id = lookup(rule.value, "id", "default")
status = lookup(rule.value, "status", "Enabled")
dynamic "abort_incomplete_multipart_upload" {
for_each = lookup(rule.value, "abort_incomplete_multipart_upload_days", null) != null ? [rule.value.abort_incomplete_multipart_upload_days] : []
content {
days_after_initiation = abort_incomplete_multipart_upload.value.days_after_initiation
}
}
}
}
}
There are basically two issues:
- The
lookup
was looking for a non-existing key in your map,abort_incomplete_multipart_upload
, instead ofabort_incomplete_multipart_upload_days
- Because of the first error, it was propagated to the value you wanted, i.e.,
rule.value.abort_incomplete_multipart_upload
instead ofrule.value.abort_incomplete_multipart_upload_days
This code yields the following output:
# aws_s3_bucket_lifecycle_configuration.default[0] will be created
resource "aws_s3_bucket_lifecycle_configuration" "default" {
bucket = (known after apply)
id = (known after apply)
rule {
id = "default"
status = "Enabled"
}
rule {
id = "abort-incomplete-multipart-upload-lifecyle-rule"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 6
}
}
}
However, if you want it to be one rule (i.e., the example output you want), you need to make a change to your lifecycle_rule
variable:
lifecycle_rule = [
{
expiration = {
days = 7
}
id = "abort-incomplete-multipart-upload-lifecyle-rule"
abort_incomplete_multipart_upload_days = {
days_after_initiation = 6
}
}
]
This gives:
resource "aws_s3_bucket_lifecycle_configuration" "default" {
bucket = (known after apply)
id = (known after apply)
rule {
id = "abort-incomplete-multipart-upload-lifecyle-rule"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 6
}
}
}