如何使用 Bicep 在函数应用程序中组合动态设置和静态设置?

Kzr*_*tof 4 azure azure-devops azure-rm-template azure-functions azure-bicep

我正在尝试定义使用的设置(静态和动态Function AppBicep

以下是生成自身的模块Function App。该模块包含一个循环,该循环创建动态设置的集合(确实有效):

param serverFarmId string
param availableHubs array

resource functionAppProdSlotResource 'Microsoft.Web/sites@2021-03-01' = {
  name:'function-app-name'
  location: 'Canada Central'
  kind: 'functionapp,linux'
  identity: {
     type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: serverFarmId
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'dotnet|3.1'
      appSettings: [for (availableHubId, hubIndex) in availableHubs: {
        'name': 'AvailableHubsConfiguration__Hub__${hubIndex}'
        'value': 'Endpoint=https://hub-${availableHubId}.service.signalr.net;AccessKey=${listKeys(resourceId('Microsoft.SignalRService/SignalR', 'hub-${availableHubId}'), providers('Microsoft.SignalRService', 'SignalR').apiVersions[0]).primaryKey};Version=1.0;'
      }]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

不过,我还有另一个模块,它定义了同一功能的静态设置:

param functionIdentity object = {
  prodSlotName: ''
  stagingSlotName: ''
}
@secure()
param systemStorageAccountConnectionString string
param applicationInsightsInstrumentationKey string
param stsDiscoveryEndpoint string
param accountsManagerEndpoint string
param azureActiveDirectory object
param updateManagerClientIdKeyVaultUrl string
param updateManagerClientSecretKeyVaultUrl string

var functionExtensionVersion = '~4'
var functionWorkerRuntime = 'dotnet-isolated'

resource prodSlotAppSettingsResource 'Microsoft.Web/sites/config@2021-03-01' = {
  name: '${functionIdentity.prodSlotName}/appsettings'
  properties: {
    AzureWebJobsStorage: systemStorageAccountConnectionString
    FUNCTIONS_EXTENSION_VERSION: functionExtensionVersion
    FUNCTIONS_WORKER_RUNTIME: functionWorkerRuntime
    APPINSIGHTS_INSTRUMENTATIONKEY: applicationInsightsInstrumentationKey
    StsConfiguration__DiscoveryEndpoints__0: stsDiscoveryEndpoint
    AccountsManagerConfiguration__Endpoint: accountsManagerEndpoint
    AzureActiveDirectoryConfiguration__ClientId: '@Microsoft.KeyVault(SecretUri=${updateManagerClientIdKeyVaultUrl})'
    AzureActiveDirectoryConfiguration__ClientSecret: '@Microsoft.KeyVault(SecretUri=${updateManagerClientSecretKeyVaultUrl})' 
    AzureActiveDirectoryConfiguration__Scope: azureActiveDirectory.scope
    AzureActiveDirectoryConfiguration__TokenEndpoint: azureActiveDirectory.tokenEndpoint
    AzureActiveDirectoryConfiguration__TenantId: subscription().tenantId
    AzureActiveDirectoryConfiguration__SubscriptionId: subscription().subscriptionId  
  }
}
Run Code Online (Sandbox Code Playgroud)

问题

问题是第二个模块覆盖了第一个模块设置的动态设置。由于第一个模块中的循环,我找不到一种方法来阻止第二个模块的覆盖或以某种方式将两者结合起来。

问题

如何使用 Bicep 在函数应用程序中组合动态设置和静态设置?

Kzr*_*tof 5

我花了几周的时间寻找实际的解决方案。我发现的依赖于concat函数。

我删除了第二个模块(它用于为函数设置定义资源),只保留第一个模块(它具有函数资源本身以及动态设置)。

我现在用我构建的数组调用第一个模块:

module functionAppModule 'modules/function-app.bicep' = {
  name: 'Function_App'
  dependsOn: [
    serverFarmModule
  ]
  params: {
    [...]
    availableHubs: [for availableHub in availableHubs: 'Endpoint=https://hub-${environment}-${availableHub}.service.signalr.net;AccessKey=${listKeys(resourceId('Microsoft.SignalRService/SignalR', 'hub-${environment}-${availableHub}'), providers('Microsoft.SignalRService', 'SignalR').apiVersions[0]).primaryKey};Version=1.0;']
  }
}
Run Code Online (Sandbox Code Playgroud)

在该模块中,我构建了 2 个不同的数组:一个具有静态设置,另一个具有动态设置:

var staticSettings = [
  {
    name: 'FUNCTIONS_EXTENSION_VERSION'
    value: '~4'
  }
  {
    name: 'FUNCTIONS_WORKER_RUNTIME'
    value: 'dotnet-isolated'
  }
  {
    name: 'AzureWebJobsStorage'
    value: systemStorageAccountConnectionString
  }
  {
    name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
    value: applicationInsightsInstrumentationKey
  }
  [...]
]

var dynamicSettings = [for (availableHub, hubIndex) in availableHubs: {
  
  name: 'AvailableHubsConfiguration__Hub__${hubIndex}'
  value: availableHub
}]
Run Code Online (Sandbox Code Playgroud)

然后,使用该concat函数将数组合并在一起:

var functionSettings = concat(staticSettings, dynamicSettings)
Run Code Online (Sandbox Code Playgroud)

最后,我可以functionSettings通过循环遍历数组并指定名称和值,将合并的数组分配给 Function App:

resource functionAppProdSlotResource 'Microsoft.Web/sites@2021-03-01' = {
  name: 'function-app-name'
  location: 'Canada Central'
  kind: 'functionapp,linux'
  identity: {
     type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: serverFarmId
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'dotnet|3.1'
      appSettings: [for setting in functionSettings: {
        name: setting.name
        value: setting.value
      }]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)