The true and false result expressions must have consistent types. The given expressions are object and tuple, respectively

locals {
  customer_env = [
    for key, customer_env in var.customer_env : {
      key          = key
      customer_env = customer_env
    }
  ]
  domain_names = [
    for key, domain_names in var.domain_names : {
      key          = key
      domain_names = domain_names
    }
  ]

  customer_env_x_domain_names = [
    for pair in setproduct(local.customer_env, local.domain_names) : {
      customer_env = local.customer_env[pair[0].key].customer_env
      domain_names = local.domain_names[pair[1].key].domain_names
    }
  ]
}


resource "aws_route53_record" "record" {
  for_each = var.env == "prod" ? {
    for i in local.customer_env_x_domain_names : "${i.customer_env}.${i.domain_names}" => i
  } : []

  zone_id = data.aws_route53_zone.zone[each.value.domain_names].zone_id
  name    = "${each.value.customer_env}-${var.ec2-region-short}.${var.env}.${each.value.domain_names}"
  type    = "A"

  alias {
    name                   = aws_lb.lb[0].dns_name
    zone_id                = aws_lb.lb[0].zone_id
    evaluate_target_health = true
  }
}

Error: Inconsistent conditional result types

  on route53.tf line 123, in resource "aws_route53_record" "record":
 123:   for_each = var.env == "prod" ? {
 124:     for i in local.customer_env_x_domain_names : "${i.customer_env}.${i.domain_names}" => i
 125:   } : []
    |----------------
    | local.customer_env_x_domain_names is tuple with 2 elements
    | var.env is "foo"

The true and false result expressions must have consistent types. The given
expressions are object and tuple, respectively.

Hi @FernandoMiguel,

This error is caused by the fact that your for_each conditional does not use the same type of value for both the true and the false cases. The true expression is a for expression using {} and is thus producing a mapping value (an object, specifically) while your false condition is [], which produces a sequence value (a tuple).

It looks like your goal is to have no instances of aws_route53_record.record if var.env is not "prod", in which case it should work to set the false expression to {} instead of [], so that it will be an empty object.

Terraform should then be able to see that both of these values have a base type in common: both should be convertible to a map of whatever object type local.customer_env_x_domain_names is a sequence of.

  for_each = var.env == "prod" ? {
    for i in local.customer_env_x_domain_names :
    "${i.customer_env}.${i.domain_names}" => i
  } : {}

I can’t see how local.customer_env_x_domain_names is defined here, but in order for this to work it must have a consistent type for all of its elements. One way to force that is to wrap either tolist(...) or toset(...) around the value (depending on whether the order is significant), which will then force Terraform to find a common type for all of the elements because that’s a requirement for both list and set types. If it cannot do so, it should give you some feedback on what is inconsistent in an error message so you can fix it.

locals {
  customer_env_x_domain_names = toset([
    # ... whatever elements this local value has ....
  ])
}
1 Like

perfect @apparentlymart