How do I use s3 lifeycle rules in Terraform in a modular form, i.e. referenced in separate JSON?

Viewed 1153

Currently, I'm specifying lifecycle_rule under my s3 resource:

resource "aws_s3_bucket" "bucket-name" {
  bucket = "bucket-name"
  
  lifecycle_rule {
    id = "Expiration Rule"
    enabled = true
    prefix = "reports/"

  expiration {
    days = 30
    }
  }
}

...but I imagine there must be a way to make this more modular, like putting the lifecycle rule into a separate JSON so I can reference it for multiple s3 buckets and reduce the need to edit each resource. I know how to do this in general and have done this with other resources as seen here:

resource "aws_iam_policy" "devops-admin-write" {
  name = "devops-admin-s3"
  description = "Devops-Admin group s3 policy."
  policy = file("iam_policies/devops-admin-write.json")
}

...the difference is that "lifecycle_rule" is an argument and not an attribute - and it's not clear to me how to make it work. Google-Fu has not yielded any clear answers either.

1 Answers

You can use dynamic blocks that you execute with a generic local variable. So you just need to change the local variable and changes will reflect in all places where this variable is used.

To make it more maintainable I would suggest building a module and reusing the module or using an exiting module.

But the locals + dynamic implementation could look like this:

locals {
  lifecycle_rules = [
    {
      id      = "Expiration Rule"
      enabled = true
      prefix  = "reports/"
      expiration = {
        days = 30
      }
    }
  ]
}

resource "aws_s3_bucket" "bucket-name" {
  bucket = "bucket-name"
  
  dynamic "lifecycle_rule" {
    for_each = local.lifecycle_rules
   
    content {
      id      = lifecycle_rule.each.id
      enabled = lifecycle_rule.each.enabled
      prefix  = lifecycle_rule.each.prefix

      expiration {
        days = lifecycle_rule.each.expiration.days
      }
    }
  }
}

This does not check for errors and is not complete of course - it just implements your example.

See a more complete generic example in our terraform s3-bucket module: find code here

Related