Search code examples
amazon-web-servicesamazon-s3terraformterraform-provider-aws

terraform: Overriding same variables in different tf files


I have 2 buckets A and B which requires lifecycle polices but different expiration days.

Since they both are root modules in same directory they share common variables.tf file

Lifecycle policy code for both A and B

Note:- both the bucket code are in different file as both have different configurations

Bucket A file's code

resource "aws_s3_bucket_lifecycle_configuration" "A_log" {
  bucket = aws_s3_bucket.A.bucket # for B bucket aws_s3_bucket.B.bucket
  rule {
    id     = "expire current version after ${var.s3_expiration_days}, noncurrent version after ${var.s3_noncurrent_version_expiration_days} days"
    status = "Enabled"
    expiration {
      days = var.s3_expiration_days
    }
    noncurrent_version_expiration {
      noncurrent_days = var.s3_noncurrent_version_expiration_days
    }
  }
}

B bucket's file code

 resource "aws_s3_bucket_lifecycle_configuration" "B_log" {
      bucket = aws_s3_bucket.B.bucket 
      rule {
        id     = "expire current version after ${var.s3_expiration_days}, noncurrent version after ${var.s3_noncurrent_version_expiration_days} days"
        status = "Enabled"
        expiration {
          days = var.s3_expiration_days
        }
        noncurrent_version_expiration {
          noncurrent_days = var.s3_noncurrent_version_expiration_days
        }
      }
    }

variables.tf

bucket A needs 30( current) and 3 day ( non current versions) to expire, however B bucket needs 0 ( current) and 90 ( non current versions) respectively.

How do I achieve this?

Note:- I do not want to hardcode value for any of the bucket.

variable "s3_expiration_days" {
  type        = number
  description = "S3 bucket objects expiration days https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration#days"
  default     = 30
}

variable "s3_noncurrent_version_expiration_days" {
  type        = number
  description = "S3 bucket noncurrent version objects expiration days https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration#noncurrent_days"
  default     = 3
}

Solution

  • I think the easiest and most scalable way would be to do it through a single variable map:

    variable "buckets_config" {
      default = {
        "bucket-name-a" = {
           s3_expiration_days = 30
           s3_noncurrent_version_expiration_days = 3
        }
        "bucket-name-b" = {
           s3_expiration_days = 0
           s3_noncurrent_version_expiration_days = 90
        }    
      }
    }
    
    # then
    
    resource "aws_s3_bucket" "bucket" {
      for_each = var.buckets_config
      bucket = each.key
    }
    
    resource "aws_s3_bucket_lifecycle_configuration" "A_log" {
      for_each = var.buckets_config
      bucket = aws_s3_bucket.bucket[each.key].bucket
      rule {
        id     = "expire current version after ${each.value.s3_expiration_days}, noncurrent version after ${each.value.s3_noncurrent_version_expiration_days} days"
        status = "Enabled"
        expiration {
          days = each.value.s3_expiration_days
        }
        noncurrent_version_expiration {
          noncurrent_days = each.value.s3_noncurrent_version_expiration_days
        }
      }
    }
    

    UDPATE

    For two different buckets:

    # for bucket A
    resource "aws_s3_bucket_lifecycle_configuration" "A_log" {
      bucket = aws_s3_bucket.A.bucket 
      rule {
        id     = "expire current version after ${var.buckets_config[aws_s3_bucket.A.bucket].s3_expiration_days}, noncurrent version after ${var.buckets_config[aws_s3_bucket.A.bucket].s3_noncurrent_version_expiration_days} days"
        status = "Enabled"
        expiration {
          days = var.buckets_config[aws_s3_bucket.A.bucket].s3_expiration_days
        }
        noncurrent_version_expiration {
          noncurrent_days = var.buckets_config[aws_s3_bucket.A.bucket].s3_noncurrent_version_expiration_days
        }
      }
    }
    
    
    # for bucket B
    resource "aws_s3_bucket_lifecycle_configuration" "A_log" {
      bucket = aws_s3_bucket.B.bucket 
      rule {
        id     = "expire current version after ${var.buckets_config[aws_s3_bucket.B.bucket].s3_expiration_days}, noncurrent version after ${var.buckets_config[aws_s3_bucket.B.bucket].s3_noncurrent_version_expiration_days} days"
        status = "Enabled"
        expiration {
          days = var.buckets_config[aws_s3_bucket.B.bucket].s3_expiration_days
        }
        noncurrent_version_expiration {
          noncurrent_days = var.buckets_config[aws_s3_bucket.B.bucket].s3_noncurrent_version_expiration_days
        }
      }
    }