A reference to "each.value" has been used in a context in which it unavailable

  security_groups = 2

  ingress_settings = [
  {
    "from_port"       = 5432,
    "to_port"         = 5432,
    "protocol"        = "TCP",
    "cidr_blocks"     = [var.vpc_infra_cidr_block]
  },
  {
    "from_port"       = 5432,
    "to_port"         = 5432,
    "protocol"        = "TCP",
    "security_groups" = [var.eks_node_db_access_sgs]
  }]

  egress_settings = [
    {
    "from_port"       = 5432,
    "to_port"         = 5432,
    "protocol"        = "-1",
    "cidr_blocks"     = ["0.0.0.0/0"]
  }]
  
}

## Security Groups ##

resource "aws_security_group" "aws_db_security_group" {
  count       = var.security_groups
  name        = "aws-db-security-group"
  description = "Allow 5432 traffic to k8s nodes"
  vpc_id      = var.vpc_k8s_id

  dynamic "ingress" {
    for_each = toset(local.ingress_settings)
    content {
      from_port       = lookup(each.value, "from_port", null)
      to_port         = lookup(each.value, "to_port", null)
      protocol        = lookup(each.value, "protocol", null)
      cidr_blocks     = lookup(each.value, "cidr_blocks", null)
      security_groups = lookup(each.value, "security_groups", null)
    }
  }


  dynamic "egress" {
    for_each = local.egress_settings
    content {
      from_port       = lookup(each.value, "from_port", null)
      to_port         = lookup(each.value, "to_port", null)
      protocol        = lookup(each.value, "protocol", null)
      cidr_blocks     = lookup(each.value, "cidr_blocks", null)
    }
  }

  tags = {
    Product = var.aws_tag_product,
    Name    = var.aws_tag_name,
    env     = var.aws_tag_env
  }
}

│ Error: each.value cannot be used in this context
│
│   on .terraform/modules/aws_rds_db_network/network.tf line 119, in resource "aws_security_group" "aws_db_security_group":
│  119:       cidr_blocks     = lookup(each.value, "cidr_blocks", null)
│
│ A reference to "each.value" has been used in a context in which it unavailable, such as
│ when the configuration no longer contains the value in its "for_each" expression. Remove
│ this reference to each.value in your configuration to work around this error.

Any idea what I am doing wrong? I want to keep it dynamic because I might have multiple ingress settings and have to use lookup because ingress settings keys are not always the same.

Hi @vibhuyadav,

The each object is for resource-level for_each, but this resource is using count instead and so Terraform is saying that there is no each to refer to here.

It looks like you’re intending to refer to the iterator of the dynamic "ingress" block instead. By default, a dynamic block names its iterator after the block type, so you can access the current element value in that block using ingress.value instead.

You can also choose a different name for that iterator symbol if you wish, although that’s only really necessary if you have multiple levels of dynamic blocks where the block type has the same name. The following would be an explicit way to select the ingress symbol name, but this is redundant because it’s the same as the default:

  dynamic "ingress" {
    for_each = toset(local.ingress_settings)
    iterator = "ingress" # redundant, because this is the default
    content {
      # ...
    }
  }
1 Like