Home > Net >  Accessing values in list for modules in terraform
Accessing values in list for modules in terraform

Time:08-24

I am trying to refactor some terraform code when doing an upgrade.

I'm using some S3 module that takes some lifecycle configuration rules:

module "s3_bucket" {
  source             = "../modules/s3"
  lifecycle_rule = [
    {
      id                                     = "id_name"
      enabled                                = true
      abort_incomplete_multipart_upload = 7

      expiration = {
        days = 7
      }

      noncurrent_version_expiration = {
        days = 7
      }
    }
  ]
}

Here is how the resource inside the model looks like:

resource "aws_s3_bucket_lifecycle_configuration" "main" {
  count  = length(var.lifecycle_rule) > 0 ? 1 : 0
  bucket = aws_s3_bucket.main.id
  dynamic "rule" {
    for_each = var.lifecycle_rule
    content {
      id = lookup(lifecycle_rule.value, "id", null)
      enabled = lookup(lifecycle_rule.value, "enabled", null)
      abort_incomplete_multipart_upload = lookup(lifecycle_rule.value, "abort_incomplete_multipart_upload", null)
      filter {
        and {
          prefix = lookup(lifecycle_rule.value, "prefix", null)
          tags   = lookup(lifecycle_rule.value, "tags", null)
        }
      }
    }
  }
}

Running plan gives me the following error:

on ../modules/s3/main.tf line 73, in resource "aws_s3_bucket_lifecycle_configuration" "main":
  73:       id = lookup(lifecycle_rule.id, null)

A managed resource "lifecycle_rule" "id" has not been declared in
module.s3_bucket.

2 questions:

1 - Looks like I'm not reaching the lifecycle_rule.value attribute in the list for the module, any help with the syntax?

2 - How to access the nested expiration.days value inside the module also?

Thanks!

CodePudding user response:

The first part of your question: you need to use the rule and not lifecycle_rule [1]. Make sure you understand this part:

The iterator argument (optional) sets the name of a temporary variable that represents the current element of the complex value. If omitted, the name of the variable defaults to the label of the dynamic block.

To complete the answer, accessing expiration.days is possible if you define a corresponding argument in the module. In other words, you need to add expiration block to the module code [2].

There are a couple more issues with the code you currently have:

  1. The abort_incomplete_multipart_upload is a configuration block, the same as expiration
  2. The expiration date should not be set in number of days, rather an RFC3339 format [3]
  3. The enabled value cannot be a bool, it has to be either Enabled or Disabled (mind the first capital letter) and the name of the argument is status [4] not enabled

To sum up, here's what the code in the module should look like:

resource "aws_s3_bucket_lifecycle_configuration" "main" {
  count  = length(var.lifecycle_rule) > 0 ? 1 : 0
  bucket = aws_s3_bucket.main.id
  dynamic "rule" {
    for_each = var.lifecycle_rule
    content {
      id = lookup(rule.value, "id", null)
      status = lookup(rule.value, "enabled", null)
      abort_incomplete_multipart_upload {
        days_after_initiation = lookup(rule.value, "abort_incomplete_multipart_upload", null) 
      } 
      filter {
        and {
          prefix = lookup(rule.value, "prefix", null)
          tags   = lookup(rule.value, "tags", null)
        }
      }
      expiration {
        date = lookup(rule.value.expiration, "days", null)
      }
    }
  }
}

The module should be called with the following variable values:

module "s3_bucket" {
  source             = "../modules/s3"
  lifecycle_rule = [
    {
      id                                     = "id_name"
      enabled                                = "Enabled" # Mind the value
      abort_incomplete_multipart_upload = 7

      expiration = {
        days = "2022-08-28T15:04:05Z" # RFC3339 format
      }

      noncurrent_version_expiration = {
        days = 7
      }
    }

[1] https://www.terraform.io/language/expressions/dynamic-blocks

[2] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration#expiration

[3] https://www.rfc-editor.org/rfc/rfc3339#section-5.8

[4] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration#status

  • Related