Search code examples
azureterraformazure-functionsterraform-provider-azure

Terraform doesn't update WEBSITE_CONTENTAZUREFILECONNECTIONSTRING for Azure Function App


I have a terraform code as below for a windows function app:

###############   Storage Account 

data "azurerm_storage_account" "storageAccount" {
  name                = var.storageAccountName
  resource_group_name = var.resource_group_name
}

############### File  Storage Account 

data "azurerm_storage_account" "fileStorageAccount" {
  name                = var.fileStorageAccountName
  resource_group_name = var.resource_group_name
}

###############   Application Insights 

data "azurerm_application_insights" "appInsight" {
  name                = var.appInsightName
  resource_group_name = var.resource_group_name
}

############### Service Bus 

data "azurerm_servicebus_namespace" "serviceBus" {
  name                = var.serviceBus
  resource_group_name = var.resource_group_name
}

data "azurerm_servicebus_namespace_authorization_rule" "serviceBusNamespace_auth_rule" {
  name         = var.serviceBusNamespace_auth_rule_name
  namespace_id = data.azurerm_servicebus_namespace.serviceBus.id
}

###############   App Service Plan 

data "azurerm_service_plan" "appServicePlan" {
  name                = var.appServicePlanName
  resource_group_name = var.resource_group_name
}

###############   App Settings 

locals {
  appSettings = fileexists("${var.filepath}/appSettings.json") ? jsondecode(file("${var.filepath}/appSettings.json")) : null
}
locals {
  connections = fileexists("${var.filepath}/connections.json") ? jsondecode(file("${var.filepath}/connections.json")) : null
}

data "vault_generic_secret" "secrets" {
  path = var.vault_path_function_app_conn_string
}

###############   Function App 

resource "azurerm_windows_function_app" "functionApp" {
  name                        = var.functionAppName
  resource_group_name         = var.resource_group_name
  location                    = var.location
  service_plan_id             = data.azurerm_service_plan.appServicePlan.id
  storage_account_name        = data.azurerm_storage_account.storageAccount.name
  storage_account_access_key  = data.azurerm_storage_account.storageAccount.primary_access_key
  builtin_logging_enabled     = var.builtin_logging_enabled
  client_certificate_mode     = var.client_certificate_mode
  https_only                  = var.https_only
  tags                        = var.tags
  functions_extension_version = "~1"

  app_settings = merge(local.appSettings[var.functionAppName][0],
    { "AKA_AZURESTORAGE_CONNECTIONSTRING"        = data.azurerm_storage_account.fileStorageAccount.primary_connection_string,
      "AzureServiceBusConnectionString"          = data.azurerm_servicebus_namespace_authorization_rule.serviceBusNamespace_auth_rule.primary_connection_string
      "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" = var.WEBSITE_CONTENTAZUREFILECONNECTIONSTRING == "INT_PLAN" ? data.azurerm_storage_account.storageAccount.primary_connection_string : data.azurerm_storage_account.fileStorageAccount.primary_connection_string
  })

  identity {
    type = var.identityType
  }
  site_config {
    worker_count                           = var.worker_count
    application_insights_connection_string = data.azurerm_application_insights.appInsight.connection_string #join(";", slice(split(";", nonsensitive(data.azurerm_application_insights.appInsight.connection_string)), 0, 3))
    application_insights_key               = data.azurerm_application_insights.appInsight.instrumentation_key
    ftps_state                             = var.ftps_state
    scm_minimum_tls_version                = var.scm_minimum_tls_version
    cors {
      allowed_origins     = var.allowed_origins
      support_credentials = var.support_credentials
    }
  }

  dynamic "connection_string" {
    for_each = lookup(local.connections, var.functionAppName, [])
    content {
      name  = connection_string.value.connection_string_name
      type  = connection_string.value.connection_string_type
      value = data.vault_generic_secret.secrets.data[connection_string.value.connection_string_value]
    }
  }

  depends_on = [
    data.azurerm_storage_account.storageAccount,
    data.azurerm_service_plan.appServicePlan,
    data.azurerm_storage_account.fileStorageAccount
  ]
}

The issue is WEBSITE_CONTENTAZUREFILECONNECTIONSTRING - it does not update even when the backend storage account keys have been rotated, the same storage account is being used in the app setting - AKA_AZURESTORAGE_CONNECTIONSTRING which got updated but not the other one.

Is there a reason this happens? I notice a thread in GitHub on this but couldn't find a solution - https://github.com/hashicorp/terraform-provider-azurerm/issues/22174


Solution

  • Terraform doesn't update WEBSITE_CONTENTAZUREFILECONNECTIONSTRING for Azure Function App:

    To update the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING the procedure you followed is correct. There might be an issue with the terraform configuration when it is applying with the changes once it's deployed.

    Try below steps to resolve the issue:

    You can try setting the property always_on = true under site_config block in the code as you are using the file storage account.

     site_config {
        always_on                              = true
        application_insights_connection_string = data.azurerm_application_insights.appInsight.connection_string #join(";", slice(split(";", nonsensitive(data.azurerm_application_insights.appInsight.connection_string)), 0, 3))
        application_insights_key               = data.azurerm_application_insights.appInsight.instrumentation_key
        ftps_state                             = var.ftps_state
        scm_minimum_tls_version                = var.scm_minimum_tls_version
        cors {
          allowed_origins     = var.allowed_origins
          support_credentials = var.support_credentials
        }
      }
    

    enter image description here

    Make sure that the Terraform properly observes the changes to be done and updates the app setting WEBSITE_CONTENTAZUREFILECONNECTIONSTRING. And also check that the Terraform might not be able to access the key if the configuration is not referencing it properly.

    You can also use AzCLI command az storage account keys renew to regenerate the storage account access keys per storage account if still the issue persists with the terraform configuration.

    Note: If still the issue persists, try modifying the connection string manually using portal or CLI functionality.