使用Bicep部署Azure Function FlexConsumption时遇404错误
解决Bicep部署弹性消费计划Azure Function时的404日志缺失问题
问题概述
使用Bicep模板部署包含代码的Azure Function(弹性消费计划)时,出现404部署错误。排查发现,Bicep部署会清除所有现有部署日志,包括当前新代码的部署日志,导致ARM部署引擎查询部署状态时返回404。日志消失前可见提示:
你查找的日志未找到。在消费计划中,实例会被回收,日志不会持久化。如需持久化请启用Application Insights。
核心原因
- 弹性消费计划(FlexConsumption)的Function实例会自动弹性伸缩,闲置时会被回收,默认部署日志不会持久化到本地存储
- Bicep部署过程中,旧日志被清除,而新部署日志尚未写入Application Insights时,ARM引擎查询状态就会触发404错误
- 代码部署(OneDeploy扩展)可能在Function App身份权限、存储配置未完全就绪时执行,导致部署失败且日志丢失
解决方案
- 确保日志持久化配置:完善Application Insights关联,添加强制日志发送的应用设置
- 添加权限依赖:为Function App的系统分配身份授予存储Blob读取权限,确保代码包可被访问
- 调整部署顺序:明确资源依赖关系,确保关键资源(App Insights、存储权限)就绪后再执行代码部署
- 优化部署参数:确保SAS令牌生成逻辑正确,避免权限不足或过期问题
修正后的Bicep代码
param location string = 'northeurope' param name string = '<func-name>' param storageAccountName string = '<my-storage>' param artifactBlobName string = '<blob-name-in-storage>' param subnetId string = '<subnet-id>' // 弹性消费计划 resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = { name: 'sp-${name}' location: location sku: { name: 'FC1' tier: 'FlexConsumption' capacity: 2 } kind: 'functionapp,linux' properties: { reserved: true } } // Log Analytics工作区 resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { name: 'workspace-${name}' location: location properties: any({ retentionInDays: 30 features: { searchVersion: 1 } sku: { name: 'PerGB2018' } }) } // Application Insights resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { name: 'insights-${name}' location: location kind: 'web' properties: { Application_Type: 'web' WorkspaceResourceId: logAnalytics.id } } // 引用现有存储账户 resource functionsStorageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = { name: storageAccountName } // 存储Blob数据读取角色定义(内置角色) var storageBlobDataReaderRoleId = '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' // 为Function App系统身份授予存储Blob读取权限 resource functionStorageRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(functionsStorageAccount.id, functionApp.id, storageBlobDataReaderRoleId) scope: functionsStorageAccount properties: { roleDefinitionId: storageBlobDataReaderRoleId principalId: functionApp.identity.principalId principalType: 'ServicePrincipal' } } // Function App资源 resource functionApp 'Microsoft.Web/sites@2024-04-01' = { name: name location: location kind: 'functionapp,linux' identity: { type: 'SystemAssigned' } properties: { httpsOnly: true publicNetworkAccess: 'Enabled' reserved: true vnetRouteAllEnabled: true serverFarmId: appServicePlan.id siteConfig: { appSettings: [ { name: 'AzureWebJobsStorage__accountName' value: storageAccountName } { name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: applicationInsights.properties.ConnectionString } { name: 'FUNCTIONS_WORKER_RUNTIME' value: 'node' } { name: 'FUNCTIONS_EXTENSION_VERSION' value: '~4' } // 强制日志发送到App Insights { name: 'DIAGNOSTICS_APPLICATIONINSIGHTS_ENABLED' value: 'true' } ] } functionAppConfig: { scaleAndConcurrency: { maximumInstanceCount: 100 instanceMemoryMB: 2048 alwaysReady: [] } runtime: { name: 'node', version: '20' } deployment: { storage: { type: 'blobContainer' value: 'https://${storageAccountName}.blob.${environment().suffixes.storage}/${name}' authentication: { type: 'SystemAssignedIdentity' } } } } virtualNetworkSubnetId: subnetId } } param deployTime string = utcNow('u') // 生成SAS令牌(有效1小时) var serviceSasToken = functionsStorageAccount.listServiceSas(functionsStorageAccount.apiVersion, { signedResource: 'b' signedPermission: 'rl' canonicalizedResource: '/blob/${storageAccountName}/artifacts/${artifactBlobName}' signedExpiry: dateTimeAdd(deployTime, 'PT1H') }).serviceSasToken var artifactUrl = 'https://${storageAccountName}.blob.${environment().suffixes.storage}/artifacts/${artifactBlobName}?${serviceSasToken}' // OneDeploy代码部署,依赖权限分配完成 resource functionOneDeploy 'Microsoft.Web/sites/extensions@2024-04-01' = { parent: functionApp name: 'onedeploy' dependsOn: [ functionStorageRoleAssignment ] properties: { packageUri: artifactUrl remoteBuild: false } }
关键修正点
- 添加了存储Blob数据读取角色分配,确保Function App身份有权限访问代码包所在的存储Blob
- 完善了应用设置,添加了
FUNCTIONS_WORKER_RUNTIME、FUNCTIONS_EXTENSION_VERSION以及强制日志发送到App Insights的配置 - 为OneDeploy扩展添加
dependsOn依赖,确保权限配置完成后再执行代码部署 - 修正了日志持久化相关配置,避免部署日志提前丢失
内容的提问来源于stack exchange,提问作者y. bs
相关产品推荐
相关产品推荐

