How to fix Error: Error creating Function App: StorageAccountNotFound in Terraform

TerraformINTERMEDIATEHIGHUpdated Dec 31, 2025· 97 views

This error occurs when Terraform tries to create an Azure Function App but cannot find or access the specified storage account. The issue typically stems from resource creation timing, missing dependencies, firewall rules, or incorrect storage account references in your Terraform configuration.

Quick fix

Fixes Error: Error creating Function App: StorageAccountNotFound

resource "azurerm_storage_account" "function_storage" {
  name                     = "stfunction12345678"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_linux_function_app" "example" {
  name                       = "example-function-app"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  service_plan_id            = azurerm_service_plan.example.id
  storage_account_name       = azurerm_storage_account.function_storage.name
  storage_account_access_key = azurerm_storage_account.function_storage.primary_access_key

  # Explicit dependency to ensure storage account is fully provisioned first
  depends_on = [azurerm_storage_account.function_storage]
}
  1. Add explicit dependency from Function App to storage account
  2. Verify storage account name and connection details
  3. Check firewall and network restrictions on storage account
  4. Use managed identity instead of storage keys
terraform — error
resource "azurerm_storage_account" "function_storage" {
name = "stfunction12345678"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_linux_function_app" "example" {
name = "example-function-app"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
service_plan_id = azurerm_service_plan.example.id
storage_account_name = azurerm_storage_account.function_storage.name
storage_account_access_key = azurerm_storage_account.function_storage.primary_access_key
# Explicit dependency to ensure storage account is fully provisioned first
depends_on = [azurerm_storage_account.function_storage]
}
Error: Error creating Function App: StorageAccountNotFound

What this error means

When deploying an Azure Function App with Terraform, the error 'StorageAccountNotFound' indicates that the Azure ARM API cannot locate or access the storage account that the Function App needs for its runtime storage. Azure Function Apps require a storage account for several critical functions: storing application code, managing function executions, maintaining state, and handling logs. This storage account must exist and be accessible to the Function App when it's created. The error occurs when Terraform attempts to provision the Function App but the storage account is either not yet created, not accessible due to network restrictions, or the reference in your configuration is incorrect. This is a common issue in infrastructure-as-code deployments because Terraform manages multiple resources in parallel, and the Function App may try to reference the storage account before it's fully provisioned.

Typical symptoms

  • Terraform apply fails with 'StorageAccountNotFound' error
  • Azure portal shows the Function App was not created
  • Error message includes the exact storage account name that cannot be found
  • Terraform state shows the storage account was created but Function App creation failed
  • Retry of terraform apply eventually succeeds (race condition symptom)
  • Error appears only when storage account is in a different resource group or has network restrictions

Common causes

  1. Race condition: Function App is created before the storage account finishes provisioning (missing depends_on)
  2. Incorrect storage account name reference in your Terraform configuration
  3. Storage account exists but has network firewall rules blocking Function App access
  4. Storage account is in a different resource group or subscription that the Function App cannot access
  5. Missing or incorrect storage account access key in Function App configuration
  6. Storage account uses private endpoints without proper VNET integration for the Function App

How to fix "Error: Error creating Function App: StorageAccountNotFound"

1Add explicit dependency from Function App to storage account

The most common cause is a race condition where Terraform tries to create the Function App before the storage account is fully provisioned. Add an explicit depends_on block to ensure proper ordering:

hcl
resource "azurerm_storage_account" "function_storage" {
  name                     = "stfunction12345678"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_linux_function_app" "example" {
  name                       = "example-function-app"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  service_plan_id            = azurerm_service_plan.example.id
  storage_account_name       = azurerm_storage_account.function_storage.name
  storage_account_access_key = azurerm_storage_account.function_storage.primary_access_key

  # Explicit dependency to ensure storage account is fully provisioned first
  depends_on = [azurerm_storage_account.function_storage]
}

After adding the depends_on block, run terraform apply again. This ensures Terraform waits for the storage account to complete before attempting to create the Function App.

2Verify storage account name and connection details

Ensure you're referencing the correct storage account name and that your configuration references the actual provisioned account:

hcl
# Correct: Using output of resource
resource "azurerm_linux_function_app" "example" {
  storage_account_name       = azurerm_storage_account.function_storage.name
  storage_account_access_key = azurerm_storage_account.function_storage.primary_access_key
}

# Incorrect: Hardcoded name that may not exist
resource "azurerm_linux_function_app" "example" {
  storage_account_name       = "mystorageaccount"
  storage_account_access_key = "hardcoded_key"
}

Check your Terraform plan output to verify the correct storage account values are being used:

bash
terraform plan | grep storage_account

If you see incorrect values, update your configuration to reference the actual resource outputs.

3Check firewall and network restrictions on storage account

If the storage account has firewall rules or is behind a VNET, the Function App may not be able to access it. Verify the storage account firewall settings:

hcl
resource "azurerm_storage_account" "function_storage" {
  # ... other config ...

  # For basic testing, allow all networks
  default_action             = "Allow"
  bypass                     = ["AzureServices"]
}

If you need network restrictions, configure them after the Function App is running:

hcl
resource "azurerm_storage_account_network_rules" "function_storage" {
  storage_account_id         = azurerm_storage_account.function_storage.id
  default_action             = "Deny"
  ip_rules                   = [var.allowed_ip_addresses]
  virtual_network_subnet_ids = [azurerm_subnet.function_subnet.id]
  bypass                     = ["AzureServices"]
}

For Function Apps in App Service Environments (ASE) or with VNET integration, ensure proper subnet configuration:

hcl
resource "azurerm_app_service_virtual_network_swift_connection" "example" {
  app_service_id = azurerm_linux_function_app.example.id
  subnet_id      = azurerm_subnet.function_subnet.id
}

Then apply the firewall rules after the integration is established.

4Use managed identity instead of storage keys

A more secure approach is to use managed identity to authenticate between the Function App and storage account, avoiding the need for hardcoded access keys:

hcl
resource "azurerm_linux_function_app" "example" {
  name                             = "example-function-app"
  resource_group_name              = azurerm_resource_group.example.name
  location                         = azurerm_resource_group.example.location
  service_plan_id                  = azurerm_service_plan.example.id
  storage_uses_managed_identity    = true

  identity {
    type = "SystemAssigned"
  }

  depends_on = [azurerm_storage_account.function_storage]
}

# Grant the Function App permission to access the storage account
resource "azurerm_role_assignment" "storage_blob_data_owner" {
  scope              = azurerm_storage_account.function_storage.id
  role_definition_name = "Storage Blob Data Owner"
  principal_id       = azurerm_linux_function_app.example.identity[0].principal_id

  depends_on = [azurerm_linux_function_app.example]
}

resource "azurerm_role_assignment" "storage_queue_data_contributor" {
  scope              = azurerm_storage_account.function_storage.id
  role_definition_name = "Storage Queue Data Contributor"
  principal_id       = azurerm_linux_function_app.example.identity[0].principal_id

  depends_on = [azurerm_linux_function_app.example]
}

This approach is more secure and avoids issues with access key rotation.

5Configure required app settings for private endpoints

If your storage account uses private endpoints or has network restrictions, add these required app settings to the Function App:

hcl
resource "azurerm_linux_function_app" "example" {
  name                       = "example-function-app"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  service_plan_id            = azurerm_service_plan.example.id
  storage_account_name       = azurerm_storage_account.function_storage.name
  storage_account_access_key = azurerm_storage_account.function_storage.primary_access_key

  app_settings = {
    "AzureWebJobsStorage"                = azurerm_storage_account.function_storage.primary_connection_string
    "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" = azurerm_storage_account.function_storage.primary_connection_string
    "WEBSITE_CONTENTSHARE"               = "function-content-share"
    "WEBSITE_VNET_ROUTE_ALL"             = "1"
    "WEBSITE_CONTENTOVERVNET"            = "1"
    "WEBSITE_DNS_SERVER"                 = "168.63.129.16"
  }

  depends_on = [azurerm_storage_account.function_storage]
}

These settings ensure the Function App can communicate with the storage account through VNET integration and private endpoints.

6Verify storage account exists in the same resource group

Ensure the storage account is in the same resource group as the Function App, or explicitly reference the correct resource group:

hcl
# If storage account is in a different resource group
data "azurerm_storage_account" "existing" {
  name                = "existing-storage-account"
  resource_group_name = "different-resource-group"
}

resource "azurerm_linux_function_app" "example" {
  name                       = "example-function-app"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  service_plan_id            = azurerm_service_plan.example.id
  storage_account_name       = data.azurerm_storage_account.existing.name
  storage_account_access_key = data.azurerm_storage_account.existing.primary_access_key
}

Verify the storage account exists by checking your Terraform state:

bash
terraform state show azurerm_storage_account.function_storage

If using a data source, verify Azure permissions allow access to storage accounts in other resource groups.

Advanced notes

### Understanding Azure Function App Storage Requirements

Azure Function Apps use storage accounts for three primary purposes:

1. Runtime Storage: Stores function execution metadata and bindings state
2. File Share: Hosts the application code and configuration (referenced via WEBSITE_CONTENTSHARE)
3. Queue/Blob Storage: Used by runtime triggers (queue triggers, blob triggers, etc.)

The storage account must be accessible at all times, not just during initial deployment.

### Storage Account Naming Restrictions

Azure storage account names have strict requirements:
- Must be between 3 and 24 characters
- Only lowercase letters and numbers
- Must be globally unique

Avoid naming conflicts by including a unique identifier or environment suffix. For example: stfuncprod123 or stfuncdev456.

### Race Conditions and Terraform Parallelism

By default, Terraform creates resources in parallel when possible. For Function Apps that depend on storage accounts, explicit depends_on is essential because Terraform cannot automatically infer the dependency from the resource references in newer azurerm provider versions.

If you continue to see race conditions, you can also disable parallelism:

bash
terraform apply -parallelism=1

However, explicit dependencies are the preferred solution.

### Troubleshooting with Azure CLI

If Terraform claims the storage account doesn't exist but you can see it in Azure Portal:

bash
# List all storage accounts
az storage account list --resource-group <rg-name>

# Check if storage account is accessible
az storage account show --resource-group <rg-name> --name <storage-name>

# Verify Function App can access it
az functionapp config appsettings list --resource-group <rg-name> --name <function-app-name>

This helps identify whether the issue is with your Terraform configuration or with actual Azure permissions/resources.

Frequently asked questions

What does "Error: Error creating Function App: StorageAccountNotFound" mean?
When deploying an Azure Function App with Terraform, the error 'StorageAccountNotFound' indicates that the Azure ARM API cannot locate or access the storage account that the Function App needs for its runtime storage. Azure Function Apps require a storage account for several critical functions: storing application code, managing function executions, maintaining state, and handling logs. This storage account must exist and be accessible to the Function App when it's created.
How do I fix "Error: Error creating Function App: StorageAccountNotFound"?
This error occurs when Terraform tries to create an Azure Function App but cannot find or access the specified storage account. The issue typically stems from resource creation timing, missing dependencies, firewall rules, or incorrect storage account references in your Terraform configuration.
What causes "Error: Error creating Function App: StorageAccountNotFound"?
Race condition: Function App is created before the storage account finishes provisioning (missing depends_on) Incorrect storage account name reference in your Terraform configuration Storage account exists but has network firewall rules blocking Function App access
Is the "Error: Error creating Function App: StorageAccountNotFound" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading