使用Bicep模块创建Function App后获取默认主机密钥遇问题
问题描述
原本已实现主模板内直接创建Function App并使用其密钥的Bicep模板,现需调整为:通过主模板调用Bicep模块创建Function App,再将该Function App的密钥传入另一模块,存储为APIM机密命名值。
初始方案与编译错误
参考ChatGPT给出的方案:
// Create the Function App module functionApp 'br:azcontreg.azurecr.io/bicep/modules/functionapp:v23.01.17.01' = { name: 'functionApp' params: { functionAppName: functionAppName appServicePlanName: appServicePlanName appServicePlanResourceGroup: appServicePlanResourceGroup storageAccountName: storageAccountName storageAccountResourceGroup: storageAccountResourceGroup } } // Retrieve the Function App keys output functionAppKeys object = listKeys(functionApp.outputs.id, '2019-08-01') // Create the API Management named value module apimNamedValue 'br:azcontreg.azurecr.io/bicep/modules/apimnamedvalue:v23.01.17.01' = { name: 'apimNamedValue' scope: resourceGroup('rg-apim-${subscription().displayName}') dependsOn: [ functionApp keyVault ] params: { name: '${functionApp.outputs.appServiceName}-key' secret: true value: functionAppKeys.keys[0].value environment: environment } }
执行时出现编译错误:
This expression is being used in an argument of the function
"listKeys", which requires a value that can be calculated at the start
of the deployment. Properties of functionApp which can be calculated
at the start include "name".bicep(BCP181)
调整后的代码与部署错误
Function App模块代码
resource appService 'Microsoft.Web/sites@2021-03-01' = { name: name kind: appKind location: location tags: tags identity: { type: !empty(identityName) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned' userAssignedIdentities: !empty(identityName) ? { '${appServiceIdentity.id}': {} } : null } properties: { httpsOnly: true reserved: false serverFarmId: appServicePlan.id virtualNetworkSubnetId: !empty(vnetName) && !empty(vnetSubnetName) ? vnetSubnet.id : null } resource appServiceAppSettings 'config' = { name: 'appsettings' properties: appSettingsInternal } resource appServiceSlotConfigNames 'config' = { name: 'slotConfigNames' properties: { appSettingNames: deploymentSlotSettingNames } } resource appServiceWeb 'config' = { name: 'web' properties: { alwaysOn: alwaysOn ftpsState: 'FtpsOnly' healthCheckPath: healthCheckPath ipSecurityRestrictions: ipSecurityRestrictions use32BitWorkerProcess: use32BitProcess vnetRouteAllEnabled: vnetRouteAll } } } output appServiceId string = appService.id
主模板调用Function App模块
module functionApp 'br:crbicepregistryprod001.azurecr.io/bicep/modules/appservice:v23.04.13.01' = { name: 'functionApp' params: { name: functionAppName appServicePlanScope: functionAppServicePlanEnv.rg appServicePlanName: functionAppServicePlanEnv.name appKind: 'functionapp' vnetName: 'vnet-${environment}-uksouth' vnetSubnetName: functionAppServicePlanEnv.subnet ipSecurityRestrictions: functionAppIpSecurityRestrictions appSettings: functionAppSettings enableSlot: false alwaysOn: true healthCheckPath: '/health' } dependsOn: [ appInsights keyVault ] }
主模板调用APIM命名值模块
module apimNamedValue 'br:crbicepregistryprod001.azurecr.io/bicep/modules/apimnamedvalueforlistkeys:v23.06.13.02' = { name: 'apimNamedValue' scope: resourceGroup('rg-apim-${subscription().displayName}') dependsOn: [ functionApp keyVault ] params: { name: '${functionApp.outputs.appServiceName}-key' secret: true resourceId: functionApp.outputs.appServiceId environment: environment } }
APIM命名值模块代码(用于获取密钥)
@description('Name of the NamedValue to deploy') param name string @description('Resource Id to be used in the listkeys function') param resourceId string @description('Used in listkeys function') param apiVersion string = '2022-09-01' @description('Specify if the value is secret. Defaults to false') param secret bool = false @description('Specify if the value is a key vault reference. Also implies value is secret. Defaults to false') param keyVaultReference bool = false @description('APIM environment to deploy to') @allowed([ 'dev' 'int' 'act' 'prod' ]) param environment string = 'dev' var apimName = { dev: 'apim-dev-002' int: 'apim-int-001' act: 'apim-act-001' prod: 'apim-prod-002' }[environment] var value = listKeys(resourceId, apiVersion) resource apim 'Microsoft.ApiManagement/service@2021-08-01' existing = { name: apimName resource apimNamedValue 'namedValues' = { name: name properties: { displayName: name secret: secret || keyVaultReference keyVault: keyVaultReference ? { secretIdentifier: value } : null value: !keyVaultReference ? value : null } } } output namedValueId string = apim::apimNamedValue.id output namedValueName string = apim::apimNamedValue.name output namedValueNameFormatted string = '{{${apim::apimNamedValue.name}}}'
部署错误信息
在Azure门户查看资源组部署时,仅返回如下错误:
{ "code": "BadRequest", "message": "" }
错误猜测
推测错误原因是:APIM模块运行在APIM所在的资源组范围内,尝试访问另一资源组中Function App的密钥时,因权限或跨资源组访问问题导致“未找到”错误。
内容的提问来源于stack exchange,提问作者Rob Bowman
相关产品推荐
相关产品推荐

