Reference resource after "for_each"

Hello, I have a little problem here:

In variables.tf

variable "sp_name" {
  type    = set(string)
  default = ["ASP-CriticalApp-TESTA", "ASP-CriticalApp-TESTB"]
}

variable "af_name" {
  type    = set(string)
  default = ["SFT-FUNCTAPP-TESTA", "SFT-FUNCTAPP-TESTB"]
}

In main.tf

resource "azurerm_service_plan" "sp" {
  for_each            = toset(var.sp_name)
  name                = each.value
  resource_group_name = data.azurerm_resource_group.rg.name
  location            = data.azurerm_resource_group.rg.location
  os_type             = "Windows"
  sku_name            = "Y1"
}

resource "azurerm_windows_function_app" "af" {
  for_each            = toset(var.af_name)
  name                = each.value
  resource_group_name = data.azurerm_resource_group.rg.name
  location            = data.azurerm_resource_group.rg.location

  storage_account_name       = data.azurerm_storage_account.sa.name
  storage_account_access_key = data.azurerm_storage_account.sa.primary_access_key
  service_plan_id            = azurerm_service_plan.sp[each.value].id

...
}

In main.tf in service_plan_id I’m trying to reference β€œresource β€œazurerm_service_plan” β€œsp”” but I get this error:

Error: Invalid index
β”‚
β”‚   on main.tf line 27, in resource "azurerm_windows_function_app" "af":
β”‚   27:   service_plan_id            = azurerm_service_plan.sp[each.value].id
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ azurerm_service_plan.sp is object with 2 attributes
β”‚     β”‚ each.value is "SFT-FUNCTAPP-TESTA"
β”‚
β”‚ The given key does not identify an element in this collection value.
β•΅
β•·
β”‚ Error: Invalid index
β”‚
β”‚   on main.tf line 27, in resource "azurerm_windows_function_app" "af":
β”‚   27:   service_plan_id            = azurerm_service_plan.sp[each.value].id
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ azurerm_service_plan.sp is object with 2 attributes
β”‚     β”‚ each.value is "SFT-FUNCTAPP-TESTB"
β”‚
β”‚ The given key does not identify an element in this collection value.

It should creates 4 resourcers but instead it only creates 2. I want to reference the 2 resources created in β€œazurerm_service_plan” β€œsp” and each resource join the β€œA” with the β€œazurerm_windows_function_app” β€œaf” β†’ β€œA” and so. Thank you.

(Tried with β€œeach.key” too)

Hi @Villaran92,

With the two input variables you’ve declared here, Terraform has no automatic way to recognize the relationships between the instances of your two resources.

For this to work you would need to describe to Terraform a rule for matching the instances. You described a rule about matching the letters at the end of the names, and it is possible in principle to write an expression that would create a map with these names grouped by their last letters, but I would recommend against that because it seems overly complicated and likely to be misunderstood by a future maintainer of your module.

Instead, the more straightforward answer would be to use a single input variable which directly describes the relationships you need. For example:

variable "things" {
  type = map(object({
    service_plan_name = string
    function_app_name = string
  }))
}

I’ve named it β€œthings” only because it’s not clear from your question what a pair of service plan and function app represents in your system. You should choose a plural noun that makes sense for whatever this is a collection of.

With the variable declared in this way, you can use for_each = var.things for both resources, and then use each.value.service_plan_name to refer to the service plan name, and each.value.function_app_name to refer to the function app name.

Because the two names are always paired together in a single object, it’s clear from the data structure which two names should be used for each pair of instances.

1 Like

Thank you so much for the help! I’m going to try this right now, thank you!