azureterraform

Azure Function App Multiple Connection Strings Via Terraform


I am trying to add multiple connection string in an azure function app settings via the terraform but getting error

resource "azurerm_linux_function_app" "ali_test_fa" {
name                       = local.function_app_function_app_name
resource_group_name        = data.azurerm_resource_group.sandbox_resource_group.name
location                   = 
data.azurerm_resource_group.sandbox_resource_group.location
service_plan_id            = azurerm_service_plan.ali_test_asp.id
storage_account_name       = azurerm_storage_account.ali_test_fa_st.name
storage_account_access_key = azurerm_storage_account.ali_test_fa_st.primary_access_key
tags                       = local.tags
dynamic "connection_string" {
for_each = toset(local.connection_strings)
content {
  name  = each.value.name
  type  = each.value.type
  value = each.value.value
}

}

Error: each.value cannot be used in this context
│
│   on resource_linux_function-app.tf line 26, in resource "azurerm_linux_function_app" "ali_test_fa":
│   26:       name  = each.value.name
│
│ A reference to "each.value" has been used in a context in which it is 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.
╵
╷
│ Error: each.value cannot be used in this context
│
│   on resource_linux_function-app.tf line 27, in resource "azurerm_linux_function_app" "ali_test_fa":
│   27:       type  = each.value.type
│
│ A reference to "each.value" has been used in a context in which it is 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.
╵
╷
│ Error: each.value cannot be used in this context
│
│   on resource_linux_function-app.tf line 28, in resource "azurerm_linux_function_app" "ali_test_fa":
│   28:       value = each.value.value
│
│ A reference to "each.value" has been used in a context in which it is 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.

I have specified connection strings like following:

local = {
connection_strings = [
    {
      value = "I am a sensitive sql database connection string"
      type  = "SQLServer"
      name  = "connection_string_sql_database"
    }
  ]
}

I have tried following but no success:

for_each = local.connection_strings
or
for_each = { for inst in local.connection_strings : inst.name => inst }

Update1 : Looks like following worked

dynamic "connection_string" {
for_each = local.connection_strings
content {
  name  = connection_string.value.name
  type  = connection_string.value.type
  value = connection_string.value.value
}

}


Solution

  • 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.

    The error each.value cannot be used in this context means that there is no each.value to refer here with the dynamic "connection_string" block as you are defining input as a list of maps.

    Modify the dynamic block as shown below if you are passing values by defining in the locals block.

    dynamic "connection_string" {
    for_each = local.connection_strings
    content {
      name  = connection_string.value.name
      type  = connection_string.value.type
      value = connection_string.value.value
    }
    

    main.tf:

    locals {
      connection_strings = [
        {
          value = "I am a sensitive sql database connection string"
          type  = "SQLServer"
          name  = "connection_string_sql_database"
        }
      ]
    }
    
    provider "azurerm" {
      features {}
      subscription_id = "xxxx"
    }
    
    resource "azurerm_resource_group" "example" {
      name     = "funcresg"
      location = "West Europe"
    }
    
    resource "azurerm_storage_account" "example" {
      name                     = "jafunctionappsa"
      resource_group_name      = azurerm_resource_group.example.name
      location                 = azurerm_resource_group.example.location
      account_tier             = "Standard"
      account_replication_type = "LRS"
    }
    
    resource "azurerm_service_plan" "example" {
      name                = "jahnewplan"
      resource_group_name = azurerm_resource_group.example.name
      location            = azurerm_resource_group.example.location
      os_type             = "Linux"
      sku_name            = "B1"
    }
    
    resource "azurerm_linux_function_app" "example" {
      name                = "jahexamplesampp"
      resource_group_name = azurerm_resource_group.example.name
      location            = azurerm_resource_group.example.location
    
      storage_account_name       = azurerm_storage_account.example.name
      storage_account_access_key = azurerm_storage_account.example.primary_access_key
      service_plan_id            = azurerm_service_plan.example.id
    
    dynamic "connection_string" {
    for_each = local.connection_strings
    content {
      name  = connection_string.value.name
      type  = connection_string.value.type
      value = connection_string.value.value
    }
    }
    site_config{}
    }
    

    Output:

    enter image description here

    enter image description here

    Alternatively, you can use variable block rather than locals by taking the input as list(object) as shown below.

    variable "connection_strings" {
      type = list(object({
        value  = string
        type  = string
        name = string
      }))
      default = [{
          value = "I am a sensitive sql database connection string"
          type  = "SQLServer"
          name  = "connection_string_sql_database"
        }] 
    }
    

    dynamic block in main.tf:

    dynamic "connection_string" {
        for_each = var.connection_strings
        content {
          name = each.value.name
          type = each.value.type
          value = each.value.value
        }
      }
    

    Reference: Template registry - azurerm_linux_function_app Github for relevant issue.