Bicep / ARM库用于应用服务,可选择性地包含证书。

huangapple go评论78阅读模式
英文:

Bicep / ARM library for App Services with optional certificates

问题

我正在开发一个 Bicep 模块,以使团队能够通过 Azure DevOps 部署 Azure App Services。当我通过 customHostnameConfiguration Json 属性指定证书时,它可以正常工作,该属性传递到 AppServices.bicep 文件,但是当我不为不需要证书绑定的 App Services 提供它时,它失败了。

我正在尝试使用Microsoft.Web/certificates@2022-03-01资源提供程序进行条件部署,特别是使用if (!empty(customHostnameConfiguration))条件。我还在资源属性上实现了三元运算符,例如name: contains(customHostnameConfiguration, 'appServiceCertificateName') ? customHostnameConfiguration.appServiceCertificateName : ''

当我在 customHostnameConfiguration json 属性中指定证书详细信息时,函数应用程序会部署,创建密钥保管库证书引用并将其绑定到特定主机名。如果我不提供 customHostnameConfiguration json 属性,函数应用程序仍然会创建,但它仍然会尝试部署证书和主机名绑定,并且会因为 Microsoft.Web/certificates@2022-03-01 名称属性为空字符串而失败。如果我提供默认值,它也会失败,因为它会尝试评估证书。

我的问题是,当在我的 App Service 库中不需要它们时,如何有条件地部署 Microsoft.Web/certificates 和 Microsoft.Web/sites/hostNameBindings@2021-03-01?

谢谢

不带证书的 App Service Json

   "basicFunctionAppConfiguration": {
        "value": {
            "name": "iac-dev-functionapp",
            "kind": "functionapp",
            "appServiceEnvironment": {
                "ResourceGroupName": "rg-eun-h1s01-dev-iac",
                "Name": "ase-eun-h1s01-dev-iac"
            }               
        }
    }

带证书的 App Service Json

"functionAppCustomDomain": {
            "value": {
                "name": "iac-dev-functionappcustomdomain",
                "kind": "functionapp",
                "appServiceEnvironment": {
                    "resourceGroupName": "rg-eun-h1s01-dev-iac",
                    "name": "ase-eun-h1s01-dev-iac"
                },
                "customHostnameConfiguration": {
                    "keyVaultName": "kv-eun-h1s01-dev-odp",
                    "keyVaultResourceGroup": "rg-eun-h1s01-dev-odp",
                    "keyVaultCertificateSecretName": "New-Wildcard-Company-com/{HiddenGUID}",
                    "customHostName": "mytestapp.mycompany.com",
                    "appServiceCertificateName": "companycert"
                }                
            }
        } 

Main.bicep

module functionApp 'br/Compute:appservice:v0.1' = {
  name: 'functionapp-${basicFunctionAppConfiguration.name}-${uniqueString(basicFunctionAppConfiguration.name)}'
  params:{
    name: basicFunctionAppConfiguration.name
    location: location
    appServiceEnvironmentId: resourceId(basicFunctionAppConfiguration.appServiceEnvironment.ResourceGroupName, 'Microsoft.Web/hostingEnvironments', basicFunctionAppConfiguration.appServiceEnvironment.Name)
    appServicePlanId: appServicePlan.outputs.resourceId
    storageAccountId: resourceId(basicFunctionAppConfiguration.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', basicFunctionAppConfiguration.diagnosticSettings.storageAccount.accountName)
    appInsightId: applicationInsights.outputs.resourceId
    kind: basicFunctionAppConfiguration.kind
  }
}


module functionAppCustomDomainKeyVault 'br/Compute:appservice:v0.1' = {
  name: 'functionapp-${functionAppCustomDomain.name}-${uniqueString(functionAppCustomDomain.name)}'
  params:{
    name: functionAppCustomDomain.name
    location: location
    appServiceEnvironmentId: resourceId(functionAppCustomDomain.appServiceEnvironment.resourceGroupName, 'Microsoft.Web/hostingEnvironments', functionAppCustomDomain.appServiceEnvironment.name)
    appServicePlanId: appServicePlan.outputs.resourceId
    storageAccountId: resourceId(functionAppCustomDomain.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', functionAppCustomDomain.diagnosticSettings.storageAccount.accountName)
    customHostnameConfiguration: functionAppCustomDomain.customHostnameConfiguration
    appInsightId: applicationInsights.outputs.resourceId
    kind: functionAppCustomDomain.kind
  }
}

App Service bicep

@description('Required. Name of the site.')
param name string

@description('Optional. Location for all Resources.')
param location string = resourceGroup().location

@description('Required. The resource ID of the app service environment to use for this resource.')
param appServiceEnvironmentId string

@description('Required. The resource ID of the app service plan to use for the site.')
param appServicePlanId string

@description('Required. Resource ID of the app insight to leverage for this resource.')
param appInsightId string

@description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
param storageAccountId string

@description('Optional. Resource ID of the diagnostic storage account.')
param diagnosticStorageAccountId string = ''

@description('Optional. Resource ID of log analytics workspace.')
param diagnosticWorkspaceId string = ''

@description('Required. Type of site to deploy.')
@allowed([
  'functionapp' // function app windows os
  'functionapp,linux' // function app linux os
  'functionapp,workflowapp' // logic app workflow
  'functionapp,workflowapp,linux' // logic app docker container
  'app' // normal web app
])
param kind string

@description('Optional. If client affinity is enabled.')
param clientAffinityEnabled bool = false

@description('Optional. If web sockets are enabled.')
param webSocketsEnabled bool = false

@description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
param appSettingsKeyValuePairs object = {}

@description('Optional. The custom hostname and key vault object for custom hostname configuration. Get and List access policy we be generated for this app service system assigned managed identity')
param customHostnameConfiguration object = {}

@description('Optional. Tags of the resource.')
param tags object = {}

//Default Values
var clientCertEnabled = false
var clientCertMode = 'Optional'
var containerSize = -1
var customDomainVerificationId = ''
var dailyMemoryTimeQuota = -1
var enabled = true
var httpsOnly = true
var hyperV = false
var keyVaultAccessIdentity
英文:

I am currently developing a bicep module to enable the team to deploy Azure App Services via Azure DevOps. It's working when I specify the certificate via the customHostnameConfiguration Json property which is passes through to the AppServices.bicep file but when I do not pass it in for App Services that do not require certificate bindings its failing.

I am trying to do a conditional deployment using the Microsoft.Web/certificates@2022-03-01 resource provider, specifically using the if (!empty(customHostnameConfiguration)) condition. I have also implemented a ternary operator on the resource properties such as name: contains(customHostnameConfiguration, 'appServiceCertificateName') ? customHostnameConfiguration.appServiceCertificateName : ''

When I specify the certificate details within the customHostnameConfiguration json property the function app deploys, creates the key vault certificate reference and binds it to the specific hostname.If I do not provide the customHostnameConfiguration json property the function app is created but it still tries to deploy the certificate and hostname binding and fails as the Microsoft.Web/certificates@2022-03-01 name property is an empty string. If I provide a default value it also fails as it tries to evaluate the certificate.

My question is how do I have a conditional deployment of the Microsoft.Web/certificates and Microsoft.Web/sites/hostNameBindings@2021-03-01 when they are not required in my App Service library?

Thanks

App Service without certificate Json

   "basicFunctionAppConfiguration": {
        "value": {
            "name": "iac-dev-functionapp",
            "kind": "functionapp",
            "appServiceEnvironment": {
                "ResourceGroupName": "rg-eun-h1s01-dev-iac",
                "Name": "ase-eun-h1s01-dev-iac"
            }               
        }
    }

App Service with certificate Json

"functionAppCustomDomain": {
            "value": {
                "name": "iac-dev-functionappcustomdomain",
                "kind": "functionapp",
                "appServiceEnvironment": {
                    "resourceGroupName": "rg-eun-h1s01-dev-iac",
                    "name": "ase-eun-h1s01-dev-iac"
                },
                "customHostnameConfiguration": {
                    "keyVaultName": "kv-eun-h1s01-dev-odp",
                    "keyVaultResourceGroup": "rg-eun-h1s01-dev-odp",
                    "keyVaultCertificateSecretName": "New-Wildcard-Company-com/{HiddenGUID}",
                    "customHostName": "mytestapp.mycompany.com",
                    "appServiceCertificateName": "companycert"
                }                
            }
        } 

Main.bicep

module functionApp 'br/Compute:appservice:v0.1'= {
  name: 'functionapp-${basicFunctionAppConfiguration.name}-${uniqueString(basicFunctionAppConfiguration.name)}'
  params:{
    name: basicFunctionAppConfiguration.name
    location: location
    appServiceEnvironmentId: resourceId(basicFunctionAppConfiguration.appServiceEnvironment.ResourceGroupName, 'Microsoft.Web/hostingEnvironments', basicFunctionAppConfiguration.appServiceEnvironment.Name)
    appServicePlanId: appServicePlan.outputs.resourceId
    storageAccountId: resourceId(basicFunctionAppConfiguration.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', basicFunctionAppConfiguration.diagnosticSettings.storageAccount.accountName)
    appInsightId: applicationInsights.outputs.resourceId
    kind: basicFunctionAppConfiguration.kind
  }
}


module functionAppCustomDomainKeyVault 'br/Compute:appservice:v0.1'= {
  name: 'functionapp-${functionAppCustomDomain.name}-${uniqueString(functionAppCustomDomain.name)}'
  params:{
    name: functionAppCustomDomain.name
    location: location
    appServiceEnvironmentId: resourceId(functionAppCustomDomain.appServiceEnvironment.resourceGroupName, 'Microsoft.Web/hostingEnvironments', functionAppCustomDomain.appServiceEnvironment.name)
    appServicePlanId: appServicePlan.outputs.resourceId
    storageAccountId: resourceId(functionAppCustomDomain.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', functionAppCustomDomain.diagnosticSettings.storageAccount.accountName)
    customHostnameConfiguration: functionAppCustomDomain.customHostnameConfiguration
    appInsightId: applicationInsights.outputs.resourceId
    kind: functionAppCustomDomain.kind
  }
}

App Service bicep

@description('Required. Name of the site.')
param name string
@description('Optional. Location for all Resources.')
param location string = resourceGroup().location
@description('Required. The resource ID of the app service environment to use for this resource.')
param appServiceEnvironmentId string
@description('Required. The resource ID of the app service plan to use for the site.')
param appServicePlanId string
@description('Required. Resource ID of the app insight to leverage for this resource.')
param appInsightId string
@description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
param storageAccountId string
@description('Optional. Resource ID of the diagnostic storage account.')
param diagnosticStorageAccountId string = ''
@description('Optional. Resource ID of log analytics workspace.')
param diagnosticWorkspaceId string = ''
@description('Required. Type of site to deploy.')
@allowed([
'functionapp' // function app windows os
'functionapp,linux' // function app linux os
'functionapp,workflowapp' // logic app workflow
'functionapp,workflowapp,linux' // logic app docker container
'app' // normal web app
])
param kind string
@description('Optional. If client affinity is enabled.')
param clientAffinityEnabled bool = false
@description('Optional. If web sockets are enabled.')
param webSocketsEnabled bool = false
@description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
param appSettingsKeyValuePairs object = {}
@description('Optional. The custom hostname and key vault object for custom hostname configuration. Get and List access policy we be generated for this app service system assigned managed identity')
param customHostnameConfiguration object = {}
@description('Optional. Tags of the resource.')
param tags object = {}
//Default Values
var clientCertEnabled = false
var clientCertMode = 'Optional'
var containerSize = -1
var customDomainVerificationId = ''
var dailyMemoryTimeQuota = -1
var enabled = true
var httpsOnly = true
var hyperV = false
var keyVaultAccessIdentityResourceId = 'SystemAssigned'
var redundancyMode = 'None'
var storageAccountRequired = true
var systemAssignedIdentity = true
// var clientCertExclusionPaths = ''
// var cloningInfo = {}
// var virtualNetworkSubnetId = ''
var defaultAppSettings = {
FUNCTIONS_EXTENSION_VERSION: '~4'
FUNCTIONS_WORKER_RUNTIME: 'dotnet'
}
var completeAppSettings = union(defaultAppSettings, appSettingsKeyValuePairs)
var siteConfig = {
ftpsState: 'FtpsOnly'
minTlsVersion: '1.2'
netFrameworkVersion: '6.0'
alwaysOn: true
autoHealEnabled: true
http20Enabled: true
webSocketsEnabled: webSocketsEnabled 
}
//Diagnostics
var diagnosticLogsRetentionInDays = 365
var diagnosticSettingsName = 'diag-${name}-appservice-log'
var diagnosticMetricsToEnable = ['AllMetrics']
var diagnosticLogCategoriesToEnable = contains(kind, 'workflowapp') ? [
'WorkflowRuntime'
'FunctionAppLogs'
] : kind == 'functionapp' ? [
'FunctionAppLogs'
] : [
'AppServiceHTTPLogs'
'AppServiceConsoleLogs'
'AppServiceAppLogs'
'AppServiceAuditLogs'
'AppServiceIPSecAuditLogs'
'AppServicePlatformLogs'
]
var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
category: category
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}]
var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
{
categoryGroup: 'allLogs'
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}
] : diagnosticsLogsSpecified
var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
category: metric
timeGrain: null
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}]
//Identity
var identityType = systemAssignedIdentity ? 'SystemAssigned' : 'None'
var identity = identityType != 'None' ? {
type: identityType
userAssignedIdentities: null
} : null
//Telemetry
var enableDefaultTelemetry = true
resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}'
properties: {
mode: 'Incremental'
template: {
'$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
contentVersion: '1.0.0.0'
resources: []
}
}
}
//KeyVault Certificate
resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = if (!empty(customHostnameConfiguration)) {
name: contains(customHostnameConfiguration, 'appServiceCertificateName') ? customHostnameConfiguration.appServiceCertificateName : ''
location: location
properties: { 
keyVaultId: resourceId(customHostnameConfiguration.keyVaultResourceGroup, 'Microsoft.KeyVault/vaults', customHostnameConfiguration.keyVaultName)
keyVaultSecretName: contains(customHostnameConfiguration, 'keyVaultCertificateSecretName') ? customHostnameConfiguration.keyVaultCertificateSecretName : ''
serverFarmId: appServicePlanId
}
}
//Create the app service
resource app 'Microsoft.Web/sites@2021-03-01' = {
name: name
location: location
kind: kind
tags: tags
identity: identity
properties: {
serverFarmId: appServicePlanId
clientAffinityEnabled: clientAffinityEnabled
httpsOnly: httpsOnly
hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? {
id: appServiceEnvironmentId
} : null
storageAccountRequired: storageAccountRequired
keyVaultReferenceIdentity: !empty(keyVaultAccessIdentityResourceId) ? keyVaultAccessIdentityResourceId : null
siteConfig: siteConfig
clientCertEnabled: clientCertEnabled
clientCertMode: clientCertMode
containerSize: containerSize != -1 ? containerSize : null
customDomainVerificationId: !empty(customDomainVerificationId) ? customDomainVerificationId : null
dailyMemoryTimeQuota: dailyMemoryTimeQuota != -1 ? dailyMemoryTimeQuota : null
enabled: enabled
hostNamesDisabled: false
hyperV: hyperV
redundancyMode: redundancyMode
}
}
// hostNameSslStates: (!empty(customHostnameConfiguration)) ? customHostnameState : null
//cloningInfo: !empty(cloningInfo) ? cloningInfo : null
//virtualNetworkSubnetId: !empty(virtualNetworkSubnetId) ? virtualNetworkSubnetId : any(null)
//clientCertExclusionPaths: !empty(clientCertExclusionPaths) ? clientCertExclusionPaths : null
resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = if (!empty(customHostnameConfiguration)) {
name: contains(customHostnameConfiguration, 'customHostName') ? customHostnameConfiguration.customHostName : '${uniqueString(deployment().name, location)}-hostnamebinding' 
parent: app
properties: {
siteName: contains(customHostnameConfiguration, 'customHostName') ? customHostnameConfiguration.customHostName : ''
sslState: 'SniEnabled'
thumbprint: !empty(appServiceCertificate) ? appServiceCertificate.properties.thumbprint : ''
}
}
//Set the default stack to dotnet
resource appSettingsStack 'Microsoft.Web/sites/config@2021-03-01' = { 
name: 'metadata' 
parent: app
properties: { 
CURRENT_STACK: 'dotnet' 
} 
}
//Save the app settings
module app_appsettings 'br/Compute:appservice/appsettings:v0.1' = if (!empty(completeAppSettings)) {
name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings'
params: {
appName: app.name
kind: kind
storageAccountId: storageAccountId
appInsightId: appInsightId
appSettingsKeyValuePairs: completeAppSettings
}
}
//Diagnostics
resource app_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId)) {
name: !empty(diagnosticSettingsName) ? diagnosticSettingsName : '${name}-diagnosticSettings'
properties: {
storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
metrics: diagnosticsMetrics
logs: diagnosticsLogs
}
scope: app
}
// Outputs     
@description('The name of the site.')
output name string = app.name
@description('The resource ID of the site.')
output appServiceResourceId string = app.id
@description('The resource group the site was deployed into.')
output resourceGroupName string = resourceGroup().name
@description('The principal ID of the system assigned identity.')
output systemAssignedPrincipalId string = systemAssignedIdentity && contains(app.identity, 'principalId') ? app.identity.principalId : ''
@description('The location the resource was deployed into.')
output location string = app.location
@description('Default hostname of the app.')
output defaultHostname string = app.properties.defaultHostName

答案1

得分: 0

所以,答案是你必须为证书和主机名绑定创建一个子模块才能使其工作。

**AppService.bicep**

@param name string
@description('Required. Name of the site.')
...
...

// Default Values
...
...

// var clientCertExclusionPaths = ''
// var cloningInfo = {}
// var virtualNetworkSubnetId = ''
...

// Outputs     
...
...

**AppServiceCertificate.bicep**

@param appServiceName string
@description('Required. Name of the app service to bind the key vault certificate.')
...
...

resource appService 'Microsoft.Web/sites@2021-03-01' existing = {
  name: appServiceName
}

resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = {
  name: appServiceCertificateName
  ...
}

resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = {
  ...
}
英文:

So, the answer here is that you have to have a sub module for the certificate and hostnaem binding for this to work.

AppService.bicep

@description('Required. Name of the site.')
param name string
@description('Optional. Location for all Resources.')
param location string = resourceGroup().location
@description('Required. The resource ID of the app service environment to use for this resource.')
param appServiceEnvironmentId string
@description('Required. The resource ID of the app service plan to use for the site.')
param appServicePlanId string
@description('Required. Resource ID of the app insight to leverage for this resource.')
param appInsightId string
@description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
param storageAccountId string
@description('Optional. Resource ID of the diagnostic storage account.')
param diagnosticStorageAccountId string = ''
@description('Optional. Resource ID of log analytics workspace.')
param diagnosticWorkspaceId string = ''
@description('Required. Type of site to deploy.')
@allowed([
'functionapp' // function app windows os
'functionapp,linux' // function app linux os
'functionapp,workflowapp' // logic app workflow
'functionapp,workflowapp,linux' // logic app docker container
'app' // normal web app
])
param kind string
@description('Optional. If client affinity is enabled.')
param clientAffinityEnabled bool = false
@description('Optional. If web sockets are enabled.')
param webSocketsEnabled bool = false
@description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
param appSettingsKeyValuePairs object = {}
@description('Optional. The custom hostname and key vault object for custom hostname configuration. Get and List access policy we be generated for this app service system assigned managed identity')
param customHostnameConfiguration object = {}
@description('Optional. Tags of the resource.')
param tags object = {}
//Default Values
var clientCertEnabled = false
var clientCertMode = 'Optional'
var containerSize = -1
var customDomainVerificationId = ''
var dailyMemoryTimeQuota = -1
var enabled = true
var httpsOnly = true
var hyperV = false
var keyVaultAccessIdentityResourceId = 'SystemAssigned'
var redundancyMode = 'None'
var storageAccountRequired = true
var systemAssignedIdentity = true
// var clientCertExclusionPaths = ''
// var cloningInfo = {}
// var virtualNetworkSubnetId = ''
var defaultAppSettings = {
FUNCTIONS_EXTENSION_VERSION: '~4'
FUNCTIONS_WORKER_RUNTIME: 'dotnet'
}
var completeAppSettings = union(defaultAppSettings, appSettingsKeyValuePairs)
var siteConfig = {
ftpsState: 'FtpsOnly'
minTlsVersion: '1.2'
netFrameworkVersion: '6.0'
alwaysOn: true
autoHealEnabled: true
http20Enabled: true
webSocketsEnabled: webSocketsEnabled 
}
//Diagnostics
var diagnosticLogsRetentionInDays = 365
var diagnosticSettingsName = 'diag-${name}-appservice-log'
var diagnosticMetricsToEnable = ['AllMetrics']
var diagnosticLogCategoriesToEnable = contains(kind, 'workflowapp') ? [
'WorkflowRuntime'
'FunctionAppLogs'
] : kind == 'functionapp' ? [
'FunctionAppLogs'
] : [
'AppServiceHTTPLogs'
'AppServiceConsoleLogs'
'AppServiceAppLogs'
'AppServiceAuditLogs'
'AppServiceIPSecAuditLogs'
'AppServicePlatformLogs'
]
var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
category: category
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}]
var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
{
categoryGroup: 'allLogs'
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}
] : diagnosticsLogsSpecified
var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
category: metric
timeGrain: null
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}]
//Identity
var identityType = systemAssignedIdentity ? 'SystemAssigned' : 'None'
var identity = identityType != 'None' ? {
type: identityType
userAssignedIdentities: null
} : null
//Telemetry
var enableDefaultTelemetry = true
resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}'
properties: {
mode: 'Incremental'
template: {
'$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
contentVersion: '1.0.0.0'
resources: []
}
}
}
//Create the app service
resource app 'Microsoft.Web/sites@2021-03-01' = {
name: name
location: location
kind: kind
tags: tags
identity: identity
properties: {
serverFarmId: appServicePlanId
clientAffinityEnabled: clientAffinityEnabled
httpsOnly: httpsOnly
hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? {
id: appServiceEnvironmentId
} : null
storageAccountRequired: storageAccountRequired
keyVaultReferenceIdentity: !empty(keyVaultAccessIdentityResourceId) ? keyVaultAccessIdentityResourceId : null
siteConfig: siteConfig
clientCertEnabled: clientCertEnabled
clientCertMode: clientCertMode
containerSize: containerSize != -1 ? containerSize : null
customDomainVerificationId: !empty(customDomainVerificationId) ? customDomainVerificationId : null
dailyMemoryTimeQuota: dailyMemoryTimeQuota != -1 ? dailyMemoryTimeQuota : null
enabled: enabled
hostNamesDisabled: false
hyperV: hyperV
redundancyMode: redundancyMode
}
}
// hostNameSslStates: (!empty(customHostnameConfiguration)) ? customHostnameState : null
//cloningInfo: !empty(cloningInfo) ? cloningInfo : null
//virtualNetworkSubnetId: !empty(virtualNetworkSubnetId) ? virtualNetworkSubnetId : any(null)
//clientCertExclusionPaths: !empty(clientCertExclusionPaths) ? clientCertExclusionPaths : null
module appServiceCertificate 'br/Compute:appservice/appservicecertificates:v0.1' = if (!empty(customHostnameConfiguration)) {
name: '${uniqueString(deployment().name, location)}-app-service-certificate'
dependsOn: [app]
params:{
appServiceName: name
appServicePlanId: appServicePlanId
keyVaultName: customHostnameConfiguration.keyVaultName
keyVaultResourceGroup: customHostnameConfiguration.keyVaultResourceGroup
keyVaultCertificateSecretName: customHostnameConfiguration.keyVaultCertificateSecretName
customHostName: customHostnameConfiguration.customHostName
appServiceCertificateName: customHostnameConfiguration.appServiceCertificateName
}
}
//Set the default stack to dotnet
resource appSettingsStack 'Microsoft.Web/sites/config@2021-03-01' = { 
name: 'metadata' 
parent: app
properties: { 
CURRENT_STACK: 'dotnet' 
} 
}
//Save the app settings
module app_appsettings 'br/Compute:appservice/appsettings:v0.1' = if (!empty(completeAppSettings)) {
name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings'
params: {
appName: app.name
kind: kind
storageAccountId: storageAccountId
appInsightId: appInsightId
appSettingsKeyValuePairs: completeAppSettings
}
}
//Diagnostics
resource app_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId)) {
name: !empty(diagnosticSettingsName) ? diagnosticSettingsName : '${name}-diagnosticSettings'
properties: {
storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
metrics: diagnosticsMetrics
logs: diagnosticsLogs
}
scope: app
}
// Outputs     
@description('The name of the site.')
output name string = app.name
@description('The resource ID of the site.')
output appServiceResourceId string = app.id
@description('The resource group the site was deployed into.')
output resourceGroupName string = resourceGroup().name
@description('The principal ID of the system assigned identity.')
output systemAssignedPrincipalId string = systemAssignedIdentity && contains(app.identity, 'principalId') ? app.identity.principalId : ''
@description('The location the resource was deployed into.')
output location string = app.location
@description('Default hostname of the app.')
output defaultHostname string = app.properties.defaultHostName

AppServiceCertificate.bicep

@description('Required. Name of the app service to bind the key vault certificate.')
param appServiceName string 
@description('Required. Resource Id of the app service plan.')
param appServicePlanId string 
@description('Optional. Location for all Resources.')
param location string = resourceGroup().location
@description('Required. Name of the keyvault where the certificate is stored.')
param keyVaultName string
@description('Required. Name of the keyvault resource group where the certificate is stored.')
param keyVaultResourceGroup string
@description('Required. Name of the keyvault certificate including version in {keyvaultname}/{version} format')
param keyVaultCertificateSecretName string
@description('Required. Custom hostname for the app service')
param customHostName string
@description('Required. Certificate name for this app service. This is registered against the resource group')
param appServiceCertificateName string
resource appService 'Microsoft.Web/sites@2021-03-01' existing = {
name: appServiceName
}
resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = {
name: appServiceCertificateName
location: location
properties: { 
keyVaultId: resourceId(keyVaultResourceGroup, 'Microsoft.KeyVault/vaults', keyVaultName)
keyVaultSecretName: keyVaultCertificateSecretName 
serverFarmId: appServicePlanId
}
}
resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = {
name: customHostName 
parent: appService
properties: {
siteName: customHostName
sslState: 'SniEnabled'
thumbprint: !empty(appServiceCertificate) ? appServiceCertificate.properties.thumbprint : ''
}
}

huangapple
  • 本文由 发表于 2023年6月29日 18:41:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定