Skip to content

can(v.property_name) may produce null and cause "Invalid for_each set argument" error #164

Open
@evgeny-goldin

Description

@evgeny-goldin

Description

for_each = toset([for v in concat([var.default_cache_behavior], var.ordered_cache_behavior) : v.cache_policy_name if can(v.cache_policy_name)])
name = each.key
}
data "aws_cloudfront_origin_request_policy" "this" {
for_each = toset([for v in concat([var.default_cache_behavior], var.ordered_cache_behavior) : v.origin_request_policy_name if can(v.origin_request_policy_name)])
name = each.key
}
data "aws_cloudfront_response_headers_policy" "this" {
for_each = toset([for v in concat([var.default_cache_behavior], var.ordered_cache_behavior) : v.response_headers_policy_name if can(v.response_headers_policy_name)])
uses the following expression:

for_each = toset([for v in concat(..) : v.property_name if can(v.property_name)])

That may produce an error if v.property_name evaluates to null (which could be its default value):

Error: Invalid for_each set argument
│
│   on .terraform/modules/s3_cloudfront.cloudfront/main.tf line 301, in data "aws_cloudfront_cache_policy" "this":301:   for_each = toset([for v in concat([var.default_cache_behavior], var.ordered_cache_behavior) : v.cache_policy_name if can(v.cache_policy_name)])
│     ├────────────────
│     │ var.default_cache_behavior is object with 7 attributes
│     │ var.ordered_cache_behavior is empty tuple
│
│ The given "for_each" argument value is unsuitable: "for_each" sets must not contain null values.

Versions

  • Module version [Required]: "4.1.0"

  • Terraform version: "1.12.0"

  • Provider version(s): "hashicorp/aws v5.98.0"

Reproduction Code [Required]

variable "cache_policy_name" {
  type        = string
  default     = null
  description = "cache control policy name. Pass name of managed or custom policy."
}

and

module "cloudfront" {
  source  = "terraform-aws-modules/cloudfront/aws"
  version = "4.1.0"
  aliases = var.cloudfront_aliases
  comment = var.cloudfront_description

  create_origin_access_identity = true

  default_cache_behavior = {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = var.multi_region ? "group_one" : "s3_one"
    viewer_protocol_policy = "redirect-to-https"
    compress               = var.cache_compress
    cache_policy_name      = var.cache_policy_name
    use_forwarded_values   = var.use_forwarded_value
  }
  ...
}

Steps to reproduce the behavior:

$ terraform plan

Expected behavior

Module runs correctly

Actual behavior

Module fails with an error:

Error: Invalid for_each set argument
│
│   on .terraform/modules/s3_cloudfront.cloudfront/main.tf line 301, in data "aws_cloudfront_cache_policy" "this":301:   for_each = toset([for v in concat([var.default_cache_behavior], var.ordered_cache_behavior) : v.cache_policy_name if can(v.cache_policy_name)])
│     ├────────────────
│     │ var.default_cache_behavior is object with 7 attributes
│     │ var.ordered_cache_behavior is empty tuple
│
│ The given "for_each" argument value is unsuitable: "for_each" sets must not contain null values.

Terminal Output Screenshot(s)

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions