Skip to content

Unable to create lifecycle_rules with filter and tags set to empty #358

@remi-f-artelia

Description

@remi-f-artelia

Description

I've set a variable object (map of object to be accurate) to loop over the creation of my buckets with this module and I've defined the lifecycle configuration within this object as a list of object.

It is defined as below (I've removed plenty of lines to keep it as small as possible here)

https://gist.github.com/remi-f-artelia/41eea5a6c9347da8950c566aa4d551af

But when I run this, I have the following error

│ Error: Invalid Attribute Value
│ 
│   with module.s3_bucket["<random-id>"].aws_s3_bucket_lifecycle_configuration.this[0],
│   on .terraform/modules/s3_bucket/main.tf line 277, in resource "aws_s3_bucket_lifecycle_configuration" "this":
│  277: resource "aws_s3_bucket_lifecycle_configuration" "this" {
│ 
│ Attribute rule[0].filter[0].and[0].tags map must contain at least 1
│ elements, got: 0

I know that the issue could be seen as the result of the PR #42041 and the multiple associated issues in the aws terraform provider, but the issue here is related to the module itself and not the aws provider.

latest related issue: 42714

I managed (with the help of an AI ;-) ) to fix the issue by updating the local .terraform module file as below

Block 1 - Line 353 (Single key argument or single tag filter)

Source (Problematic):

      # Max 1 block - filter - with one key argument or a single tag
      dynamic "filter" {
        for_each = [for v in try(flatten([rule.value.filter]), []) : v if v != null && max(length(keys(v)), length(try(rule.value.filter.tags, rule.value.filter.tag, []))) == 1]

        content {
          object_size_greater_than = try(filter.value.object_size_greater_than, null)
          object_size_less_than    = try(filter.value.object_size_less_than, null)
          prefix                   = try(filter.value.prefix, null)

          dynamic "tag" {
            for_each = try(filter.value.tags, filter.value.tag, [])

            content {
              key   = tag.key
              value = tag.value
            }
          }
        }
      }

Fixed:

      # Max 1 block - filter - with one key argument or a single tag
      dynamic "filter" {
        for_each = [for v in try(flatten([rule.value.filter]), []) : v if v != null && max(length(try(keys(v), [])), length(try(rule.value.filter.tags, rule.value.filter.tag, []))) == 1]

        content {
          object_size_greater_than = try(filter.value.object_size_greater_than, null)
          object_size_less_than    = try(filter.value.object_size_less_than, null)
          prefix                   = try(filter.value.prefix, null)

          dynamic "tag" {
            for_each = try(filter.value.tags, filter.value.tag, [])

            content {
              key   = tag.key
              value = tag.value
            }
          }
        }
      }

Block 2 - Line 373 (Multiple key arguments or multiple tags filter)

Source (Problematic):

      # Max 1 block - filter - with more than one key arguments or multiple tags
      dynamic "filter" {
        for_each = [for v in try(flatten([rule.value.filter]), []) : v if v != null && max(length(keys(v)), length(try(rule.value.filter.tags, rule.value.filter.tag, []))) > 1 && length(try(v.tags, {})) > 0]

        content {
          and {
            object_size_greater_than = try(filter.value.object_size_greater_than, null)
            object_size_less_than    = try(filter.value.object_size_less_than, null)
            prefix                   = try(filter.value.prefix, null)
            tags                     = try(filter.value.tags, filter.value.tag, null)
          }
        }
      }

Fixed:

      # Max 1 block - filter - with more than one key arguments or multiple tags
      dynamic "filter" {
        for_each = [for v in try(flatten([rule.value.filter]), []) : v if v != null && max(length(try(keys(v), [])), length(try(rule.value.filter.tags, rule.value.filter.tag, []))) > 1 && length(try(v.tags, {})) > 0]

        content {
          and {
            object_size_greater_than = try(filter.value.object_size_greater_than, null)
            object_size_less_than    = try(filter.value.object_size_less_than, null)
            prefix                   = try(filter.value.prefix, null)
            tags                     = try(filter.value.tags, filter.value.tag, null)
          }
        }
      }

Key Changes

The fix involves wrapping the keys(v) function call with try(keys(v), []) to:

  1. Prevent null value errors: The try() function catches the error when keys() receives a null value
  2. Provide safe fallback: Returns an empty list [] when keys(v) fails, allowing the length() function to work properly
  3. Maintain logic integrity: The filter logic continues to work as expected for valid filter configurations
  • ✋ I have searched the open/closed issues and my issue is not listed.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Module version [Required]: 5.7.0

  • Terraform version:

tf --version
Terraform v1.11.4
on windows_amd64

Your version of Terraform is out of date! The latest version
is 1.13.1. You can update by downloading from https://developer.hashicorp.com/terraform/install

Reproduction Code [Required]

See the code with different files in the gist

And the fixed file here

Steps to reproduce the behavior:

Are you using workspaces? => No
Have you cleared the local cache (see Notice section above)? --> Yes
List steps in order that led up to the issue you encountered --> terraform init / terraform plan -var-file $var_file

Expected behavior

No error but only the following warning I have as an output with my fixed version

Warning: Invalid Attribute Combination

  with module.s3_bucket["<random-id>"].aws_s3_bucket_lifecycle_configuration.this[0],
  on .terraform\modules\s3_bucket\main.tf line 277, in resource "aws_s3_bucket_lifecycle_configuration" "this":
 277: resource "aws_s3_bucket_lifecycle_configuration" "this" {

No attribute specified when one (and only one) of
[rule[0].filter,rule[0].prefix] is required

This will be an error in a future version of the provider

but I hope this will be fixed with the help of the following issue

Actual behavior

An error that prevents my pipeline to run (works only locally with my fixed version)

Terminal Output Screenshot(s)

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions