Mismatch in condition in for_each: The true and false result expressions must have consistent types

Hi

I have the following local defined:

local.management_custom_policy_definition_content_list
[
  {
    "content" = {
      "properties" = {
        "description" = "This policy governs that all Azure resources have a lower-case naming scheme."
        "displayName" = "Enforce lower-case names for all Azure resources."
        "metadata" = {
          "category" = "Network"
        }
        "mode" = "All"
        "name" = "pol-def-fnd-namecasing-001"
        "parameters" = {
          "Effect" = {
            "allowedValues" = [
              "Audit",
              "Deny",
            ]
            "defaultValue" = "Audit"
            "metadata" = {
              "description" = "The effect of the policy rule."
              "displayName" = "Effect"
            }
            "type" = "String"
          }
          "ResourceTypesExcludedFromLowercaseConvention" = {
            "metadata" = {
              "description" = "The list of resource types excluded from the lower case naming convention."
            }
            "type" = "array"
          }
        }
        "policyRule" = {
          "if" = {
            "allof" = [
              {
                "field" = "type"
                "notin" = "[parameters('ResourceTypesExcludedFromLowercaseConvention')]"
              },
              {
                "field" = "name"
                "notmatch" = "[toLower(field('name'))]"
              },
            ]
          }
          "then" = {
            "effect" = "[parameters('Effect')]"
          }
        }
      }
    }
    "management_group_id" = "2bd25572-438e-400c-b9db-c2b61afa8d2f"
    "name" = "pol-def-fnd-namecasing-001"
  },
  {
    "content" = {
      "properties" = {
        "description" = "This policy checks for tags on resource groups"
        "displayName" = "pol-def-fnd-tag-001"
        "metadata" = {
          "category" = "TAG"
        }
        "mode" = "All"
        "name" = "pol-def-fnd-tag-001"
        "parameters" = {
          "Effect" = {
            "allowedValues" = [
              "Audit",
              "Deny",
              "Disabled",
            ]
            "defaultValue" = "Audit"
            "metadata" = {
              "description" = "The effect of the policy rule."
              "displayName" = "Effect"
            }
            "type" = "String"
          }
          "tagName" = {
            "type" = "string"
          }
        }
        "policyRule" = {
          "if" = {
            "allOf" = [
              {
                "equals" = "Microsoft.Resources/subscriptions/resourceGroups"
                "field" = "type"
              },
              {
                "exists" = "false"
                "field" = "[concat('tags[', parameters('tagName'), ']')]"
              },
            ]
          }
          "then" = {
            "effect" = "[parameters('Effect')]"
          }
        }
      }
    }
    "management_group_id" = "2bd25572-438e-400c-b9db-c2b61afa8d2f"
    "name" = "pol-def-fnd-tag-001"
  },
]

I have the following for_each loop:

module "policy_definition_management" {
  for_each            = local.management_custom_policy_definition_content_list != null ? { for def in local.management_custom_policy_definition_content_list : "${def.management_group_id}.${def.name}" => def } : {}
  source              = "./modules/azurerm/policy_definition"
  management_group_id = data.azurerm_management_group.management_group[each.value.management_group_id].id
  category            = each.value.content.properties.metadata.category
  description         = each.value.content.properties.description
  display_name        = each.value.content.properties.displayName
  mode                = each.value.content.properties.mode
  name                = each.value.content.properties.name
  parameters          = each.value.content.properties.parameters
  policy_rule         = each.value.content.properties.policyRule
}

When performing a plan, I have the following error:

│ Error: Inconsistent conditional result types
│
│   on main.tf line 320, in module "policy_definition_management":
│  320:   for_each            = local.management_custom_policy_definition_content_list != null ? { for def in local.management_custom_policy_definition_content_list : "${def.management_group_id}.${def.name}" => def } : {}
│     ├────────────────
│     │ local.management_custom_policy_definition_content_list is tuple with 2 elements
│
│ The true and false result expressions must have consistent types. The 'true' value includes object attribute
│ "2bd25572-438e-400c-b9db-c2b61afa8d2f.pol-def-fnd-namecasing-001", which is absent in the 'false' value.

I use this a lot and with all my other code it is working. But can’t figure out what is going wrong here. Anybody that has an idea? Thanks!

So I solved it in the meantime. For those wondering: it’s the jsondecode(file(xxx) that gives the error. So I do the read of the file in the module itself (first had it in a different local):

  management_custom_policy_definition_content_list = local.management_definitions_all != null ? [
    for def in local.management_definitions_all : {
      name                = def.definition_name
      management_group_id = def.management_group_id
      content             = jsondecode(file("./definitions/${def.definition_name}.json"))
    } if def.custom
  ] : null

→ I do it in the module

module "policy_definition_management" {
  for_each            = local.management_definitions_all != null ? { for def in local.management_definitions_all : "${def.management_group_id}.${def.definition_name}" => def if def.custom } : {}
  source              = "./modules/azurerm/policy_definition"
  management_group_id = data.azurerm_management_group.management_group[each.value.management_group_id].id
  category            = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.metadata.category
  description         = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.description
  display_name        = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.displayName
  mode                = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.mode
  name                = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.name
  parameters          = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.parameters
  policy_rule         = (jsondecode(file("./definitions/${each.value.definition_name}.json"))).properties.policyRule
}

I somebody has a nicer solution, please let me know :slight_smile:
thanks!