Azure / terraform-provider-azapi

Terraform provider for Azure Resource Manager Rest API
https://registry.terraform.io/providers/Azure/azapi/latest
Mozilla Public License 2.0
193 stars 49 forks source link

Azure Function in a Flex Consumption Plan 500 Error #625

Open WTSParadigm opened 1 month ago

WTSParadigm commented 1 month ago

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." │ } │ -------------------------------------------------------------------------------- │ ╵

ms-henglu commented 1 month ago

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
    }
  }
}
WTSParadigm commented 1 month ago

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 commented 1 month ago

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

WTSParadigm commented 1 month ago

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 commented 1 month ago

I updated my original comment with the subnet resource