terraform-provider-azapi icon indicating copy to clipboard operation
terraform-provider-azapi copied to clipboard

Azure Function in a Flex Consumption Plan 500 Error

Open WTSParadigm opened this issue 1 year ago • 5 comments

I'm trying to create an azure function in a flex consumption plan. The terraform plan seems to work fine but the apply gives an error with nothing helpful even with diagnostics on.

Terraform code (let me know if you need any of the variable values):

terraform {
  required_providers {
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 2.47.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.0, < 4.1.0" #bug with 4.1 causing the plugin to crash https://github.com/hashicorp/terraform-provider-azurerm/issues/27301
    }    
    azapi = {
      source = "Azure/azapi"
    }
  }
  backend "azurerm" {}
}

resource "azurerm_subnet" "digest_subnet" {
  name                 = local.digest_subnet_name
  virtual_network_name = local.vnet_name
  resource_group_name  = local.resource_group_name
  address_prefixes     = [var.digest_ip_range]
  service_endpoints    = ["Microsoft.KeyVault", "Microsoft.Web"]
  delegation {
    name = "serverFarms"
    service_delegation {
      name    = "Microsoft.Web/serverFarms"
      actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
    }
  }
}
resource "azapi_resource" "digestPlan" {
  type                      = "Microsoft.Web/serverfarms@2023-12-01"
  schema_validation_enabled = false
  location                  = data.azurerm_resource_group.main_resource_group.location
  name                      = local.flex_service_plan_name
  parent_id                 = data.azurerm_resource_group.main_resource_group.id
  body = jsonencode({
    kind = "functionapp",
    sku = {
      tier = "FlexConsumption",
      name = "FC1"
    },
    properties = {
      reserved = true
    }
  })
}

resource "azapi_resource" "digest_processor" {
  type                      = "Microsoft.Web/sites@2023-12-01"
  schema_validation_enabled = false
  location                  = data.azurerm_resource_group.main_resource_group.location
  name                      = local.digest_app_name
  parent_id                 = data.azurerm_resource_group.main_resource_group.id
  identity {
    type         = "SystemAssigned"
    identity_ids = []
  }
  tags = merge(local.tags, {
    "paradigm:resource"                              = local.digest_app_name,
    "hidden-link: /app-insights-conn-string"         = module.application_insights.connection_string
    "hidden-link: /app-insights-instrumentation-key" = module.application_insights.ai_instrumentation_key
    "hidden-link: /app-insights-resource-id"         = module.application_insights.ai_id
  })
  body = jsonencode({
    kind = "functionapp,linux",
    identity = {
      type : "SystemAssigned"
    }
    properties = {
      serverFarmId = azapi_resource.digestPlan.id,
      httpsOnly    = true
      functionAppConfig = {
        deployment = {
          storage = {
            type  = "blobContainer",
            value = local.blobStorageAndContainer,
            authentication = {
              type = "SystemAssignedIdentity"
            }
          }
        },
        scaleAndConcurrency = {
          maximumInstanceCount = var.digestMaximumInstanceCount,
          instanceMemoryMB     = var.instanceMemoryMB
        },
        runtime = {
          name    = var.functionAppRuntime,
          version = var.functionAppRuntimeVersion
        }
      },
      siteConfig = {
        appSettings = setunion(local.shared_function_appsettings, local.digest_appsettings)
      }
      keyVaultReferenceIdentity = azurerm_user_assigned_identity.event_processor_identity.id
      virtualNetworkSubnetId    = azurerm_subnet.digest_subnet.id
    }
  })
  depends_on = [azapi_resource.digestPlan, module.application_insights, azurerm_storage_account.digest_sa]
}

Error:

Error: Failed to create/update resource │ │ with azapi_resource.digest_processor, │ on digest.tf line 81, in resource "azapi_resource" "digest_processor": │ 81: resource "azapi_resource" "digest_processor" { │ │ creating/updating Resource: (ResourceId │ "/subscriptions//resourceGroups//providers/Microsoft.Web/sites/nhub-eastus-dev-digest-fx" │ / Api Version "2023-12-01"): PUT │ https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/sites/nhub-eastus-dev-digest-fx │ -------------------------------------------------------------------------------- │ RESPONSE 500: 500 Internal Server Error │ ERROR CODE UNAVAILABLE │ -------------------------------------------------------------------------------- │ { │ "Message": "An error has occurred." │ } │ -------------------------------------------------------------------------------- │ ╵

WTSParadigm avatar Sep 24 '24 22:09 WTSParadigm

Hi @WTSParadigm,

Thank you for taking time to report this issue.

Indeed the error message returns from the API is not helpful. I tried to create a site resource with flex consumption plan, and it works. Here's my complete config, hope it could help you.


resource "azapi_resource" "resourceGroup" {
  type     = "Microsoft.Resources/resourceGroups@2021-04-01"
  name     = "acctesthenglu925"
  location = "eastus"
  body     = {} # Resource group does not require additional properties in the body
}

resource "azapi_resource" "plan" {
  type      = "Microsoft.Web/serverfarms@2023-12-01"
  parent_id = azapi_resource.resourceGroup.id
  name      = "henglufarm"
  location  = "eastus"
  body = {
    properties = {
      hyperV         = false
      perSiteScaling = false
      reserved       = true
      zoneRedundant  = false
    }
    sku = {
      tier = "FlexConsumption"
      name = "FC1"
    }
  }

}

resource "azurerm_storage_account" "example" {
  location                 = azapi_resource.resourceGroup.location
  name                     = "henglufunction"
  resource_group_name      = azapi_resource.resourceGroup.name
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azapi_resource" "digest_processor" {
  type      = "Microsoft.Web/sites@2023-12-01"
  location  = azapi_resource.resourceGroup.location
  name      = "henglufunction"
  parent_id = azapi_resource.resourceGroup.id

  identity {
    type         = "SystemAssigned"
    identity_ids = []
  }


  body = {
    kind = "functionapp,linux"
    properties = {
      siteConfig = {
        appSettings = [
          {
            name  = "storageAccountConnectionString"
            value = azurerm_storage_account.example.primary_blob_connection_string
          }
        ]
      }
      serverFarmId = azapi_resource.plan.id
      httpsOnly    = true
      functionAppConfig = {
        deployment = {
          storage = {
            type = "blobContainer"
            authentication = {
              type = "StorageAccountConnectionString"
              storageAccountConnectionStringName = "storageAccountConnectionString"
            }
            value = azurerm_storage_account.example.primary_blob_endpoint
          }
        }
        scaleAndConcurrency = {
          maximumInstanceCount = 40
          instanceMemoryMB     = 2048
        }
        runtime = {
          name    = "java"
          version = "11"
        }
      }
      # siteConfig = {
      #   appSettings = setunion(local.shared_function_appsettings, local.digest_appsettings)
      # }
      # keyVaultReferenceIdentity = azurerm_user_assigned_identity.event_processor_identity.id
      # virtualNetworkSubnetId    = azurerm_subnet.event_processor_subnet.id
    }
  }
}

ms-henglu avatar Sep 25 '24 02:09 ms-henglu

So based on your example I went back and started commenting out/adding back in each of my settings that were extra and it seems like the error is because of the virtualNetworkSubnetId property. I was basing the setting off of this page https://learn.microsoft.com/en-us/azure/templates/microsoft.web/sites?pivots=deployment-language-terraform so I'm not sure what could be wrong with it, or if it's missing some other needed property.

WTSParadigm avatar Sep 25 '24 13:09 WTSParadigm

It turned out my subnet was missing the Microsoft.Web service endpoint

WTSParadigm avatar Sep 25 '24 16:09 WTSParadigm

I spoke too soon, I assumed since I could add the VNet in the portal once it had the correct service endpoint that it would then work in terraform, but I was wrong. Still the same error, but it's definitely related to the virtual network subnet id.

WTSParadigm avatar Sep 25 '24 19:09 WTSParadigm

I updated my original comment with the subnet resource

WTSParadigm avatar Sep 25 '24 19:09 WTSParadigm

@WTSParadigm did you resolve this issue? I am currently facing the same problem with virtualNetworkSubnetId. I can't even connect it via Azure Portal, it just gives an unknown error with no further information.

trampolin avatar Nov 20 '24 10:11 trampolin

I did not resolve it. I can't get it to work through terraform but I'm able to connect to it in the portal and add the subnet there.

WTSParadigm avatar Nov 20 '24 14:11 WTSParadigm

@WTSParadigm Thanks for your response! I think I read somewhere the subnet has to be at least a /23 size in order to work with the Microsoft.App/environments service delegation which is needed to allow for a vnet integration when using Flex Consumption. Unfortunately, in my current environment I am not able to create a subnet greater than /25. What size is you subnet? Just trying to grab every straw.

trampolin avatar Nov 20 '24 15:11 trampolin

I was using /27, I'll see if I can try with /23

WTSParadigm avatar Nov 20 '24 15:11 WTSParadigm

Ok, I was finally able to try with a subnet with /23, still got the same error

WTSParadigm avatar Nov 21 '24 14:11 WTSParadigm

My hope was that once Flex Consumption was no longer in "preview" that the regular azurerm provider will start supporting flex consumption and I won't have to use azapi and then it will work. It doesn't appear to be in preview so at some point I'll try using the azurerm provider again. I was waiting on https://github.com/hashicorp/terraform-provider-azurerm/issues/26672 before switching to azurerm

WTSParadigm avatar Nov 21 '24 14:11 WTSParadigm

Also now I can't even add a subnet via the Portal. It let's me select it but throws an error when it tries to connect with no userful info. I created a support ticket for that

WTSParadigm avatar Nov 21 '24 19:11 WTSParadigm

Oh my goodness, I've been messing around with the deployment a lot today and I finally figured out my issue. https://learn.microsoft.com/en-us/azure/azure-functions/flex-consumption-plan#considerations

Virtual network integration Ensure that the Microsoft.App Azure resource provider is enabled for your subscription by following these instructions. The subnet delegation required by Flex Consumption apps is Microsoft.App/environments.

I had to register the Microsoft.App provider on my subscription. I'm now able to create the azure function with the vnet integration. @trampolin I don't think you should need a /23 though, it says you need a min of 40 ip addresses so I would think /25 should be fine, but I haven't tried that to verify.

WTSParadigm avatar Nov 21 '24 21:11 WTSParadigm

Thanks god for your experience. I was going to waste a lot of time identifying the problem.

marco-limache avatar Dec 17 '24 13:12 marco-limache

Microsoft.App/environments this is the trick, the subnet must have this delegation

zspasev-fr avatar Feb 25 '25 12:02 zspasev-fr

@zspasev-fr is correct, the delegation type for Flex Consumption function apps is different. This is documented here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-networking-options?tabs=azure-portal#regional-virtual-network-integration.

gpehlev avatar Mar 12 '25 13:03 gpehlev