1

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.
  • The error shows it's not the same code as you posted in the question. – Marko E Feb 05 '23 at 14:49
  • Sorry for that. My main issue is how do I apply varying lifecycle rules to different buckets within a list, without having to split them and have different resource blocks for them. If that was the case, i could've split it, but that makes the code redundant. I was looking for an implementation that gets the job done within a single list. Thank you @marko-e – it's_superbird Feb 06 '23 at 05:29
  • So you only want the 4th element to be different, or 3rd and 4th? – Marko E Feb 06 '23 at 07:33
  • both 3rd and 4th to have different lifecycle configurations compared to 1 and 2 – it's_superbird Feb 06 '23 at 19:02

1 Answers1

1

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

Helder Sepulveda
  • 15,500
  • 4
  • 29
  • 56