Search code examples
amazon-web-servicesamazon-s3countterraformhcl

Applying varying lifecycle policies to list of s3 buckets


I have a list of s3 buckets on which i want to apply different lifecycle policies.

variables.tf

variable "bucket_name" {    
    type    = list(any)    
    default = ["in", "out", "in-archive", "out-archive"]  
}

For the first 2 items in the list I want to have their contents deleted after 180 days. And the remaining 2 buckets to move their contents to GLACIER class and then remove them after 600 days. I have declared two different resource blocks for varying policies, but the problem is how do I make terraform to start counting index from 3rd element instead of 1st element.

resource block

resource "aws_s3_bucket" "bucket" {
    count  = length(var.bucket_name)
    bucket = "${var.bucket_name[count.index]}"
}

resource "aws_s3_bucket_lifecycle_configuration" "bucket_lifecycle_rule" {
    count  = length(aws_s3_bucket.bucket)
    bucket = aws_s3_bucket.bucket[count.index].id  ///Want this index to stop at 2nd element
    rule {
        status = "Enabled"
        id     = "bucket-lifecycle-rule"
        expiration {
            days = 180
        }
    }
}

resource "aws_s3_bucket_lifecycle_configuration" "archive_bucket_lifecycle_rule" {
    count  = length(aws_s3_bucket.bucket)
    bucket = aws_s3_bucket.bucket[count.index + 4].id   ///Want this index to begin from 3rd and end
    rule {                                              ///at 4th element
        status = "Enabled"
        id     = "archive-bucket-lifecycle-rule"
        transition {
            days          = 181
            storage_class = "GLACIER"
        }
        expiration {
            days = 600
        }
    }
}

While I approach this rule, i get an error :

in resource "aws_s3_bucket_lifecycle_configuration" "archive_bucket_lifecycle_rule":
31:   bucket = aws_s3_bucket.bucket[count.index + 2].id
├────────────────
│ aws_s3_bucket.bucket is tuple with 4 elements
│ count.index is 2

The given key does not identify an element in this collection value.

Solution

  • How about making the input variable a bit more complex to accommodate what you need...

    Here is a quick example:

    provider "aws" { region = "us-east-1" }
    
    variable "buckets" {
      type = map(any)
      default = {
        "in" : { expiration : 180, transition : 0 },
        "out" : { expiration : 120, transition : 0 },
        "in-archive" : { expiration : 200, transition : 180 },
        "out-archive" : { expiration : 360, transition : 180 }
      }
    }
    
    resource "aws_s3_bucket" "bucket" {
      for_each = var.buckets
      bucket   = each.key
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "lifecycle" {
      for_each = var.buckets
      bucket   = aws_s3_bucket.bucket[each.key].id
      rule {
        status = "Enabled"
        id     = "bucket-lifecycle-rule"
        expiration {
          days = each.value.expiration
        }
      }
      rule {
        status = each.value.transition > 0 ? "Enabled" : "Disabled"
        id     = "archive-bucket-lifecycle-rule"
        transition {
          days          = each.value.transition
          storage_class = "GLACIER"
        }
      }
    }
    
    

    Now our variable is type = map(any) we can create a more complex object there and pass the lifecycle expiration, you can make that as complex as you need to fit more complex rules