amazon-web-servicesterraformterraform-provider-aws

Invalid index in dynamic block


I have the following module:

module "nlb_mqtt_public" {
  source             = "..." # module source
  ... # other fields

  vpc_id             = module.vpc_base.vpc_id

  listen_map = {
    "8884"  = "8883"
    "50858" = "8883"
    "60858" = "60858" 
    "60859" = "60859" 
    # "28883" = "28883"
    "443" = "28883"
  }

  healthcheck_map = {
    "8883" = {
      interval = "10"
      path     = "/heartbeat"
      port     = "9090"
      protocol = "HTTP"
    }
  }
}

And in the external module that I am referencing in the source, it fails in this part:

resource "aws_lb_target_group" "this-health" {
  count             = length(var.healthcheck_map) >= 1 ? length(distinct(values(var.listen_map))) : 0
  name              = "${random_string.target.keepers.name}-port-${element(values(var.listen_map), count.index)}-${random_string.target.result}"
  protocol          = "TCP"
  port              = element(distinct(values(var.listen_map)), count.index)
  vpc_id            = var.vpc_id
  proxy_protocol_v2 = random_string.target.keepers.enable_proxy_protocol_v2

  dynamic "health_check" {
    for_each = [var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]] # it fails here
    content {
      enabled             = lookup(health_check.value, "enabled", null)
      healthy_threshold   = lookup(health_check.value, "healthy_threshold", null)
      interval            = lookup(health_check.value, "interval", null)
      matcher             = lookup(health_check.value, "matcher", null)
      path                = lookup(health_check.value, "path", null)
      port                = lookup(health_check.value, "port", null)
      protocol            = lookup(health_check.value, "protocol", null)
      timeout             = lookup(health_check.value, "timeout", null)
      unhealthy_threshold = lookup(health_check.value, "unhealthy_threshold", null)
    }
  }

  lifecycle {
    create_before_destroy = true
  }
}

and in this

data "template_file" "healthcheck_port" {
  count    = length(var.healthcheck_map) >= 1 ? length(distinct(values(var.listen_map))) : 0
  template = var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]["port"]
}

It shows the following error:

Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 51, in resource "aws_lb_target_group" "this-health":
  51:     for_each = [var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]]
    |----------------
    | count.index is 0
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.
Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 51, in resource "aws_lb_target_group" "this-health":
  51:     for_each = [var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]]
    |----------------
    | count.index is 2
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.
Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 51, in resource "aws_lb_target_group" "this-health":
  51:     for_each = [var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]]
    |----------------
    | count.index is 3
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.
Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 150, in data "template_file" "healthcheck_port":
 150:   template = var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]["port"]
    |----------------
    | count.index is 3
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.
Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 150, in data "template_file" "healthcheck_port":
 150:   template = var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]["port"]
    |----------------
    | count.index is 0
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.
Error: Invalid index
  on .terraform/modules/nlb_mqtt_public/main.tf line 150, in data "template_file" "healthcheck_port":
 150:   template = var.healthcheck_map[element(distinct(values(var.listen_map)), count.index)]["port"]
    |----------------
    | count.index is 2
    | var.healthcheck_map is map of map of string with 1 element
    | var.listen_map is map of string with 5 elements
The given key does not identify an element in this collection value.

I don't understand why. The healthcheck_map variable is defined with the type map(map(string)) and default as {}.

Previously, I had some issues in another tf files, where the error suggested me to use the -target argument, so I thought that it may be the case here too, but it does not work.


Solution

  • values returns values in alphanumerical order, not in the order you have them defined. Thus, the first value returned will be 28883. Subsequently, var.healthcheck_map["28883"] fails, because var.healthcheck_map has only 8883 key, not the required 28883.

    Basically, your values in var.listen_map do not match keys in var.healthcheck_map.