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

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

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

  1. "basicFunctionAppConfiguration": {
  2. "value": {
  3. "name": "iac-dev-functionapp",
  4. "kind": "functionapp",
  5. "appServiceEnvironment": {
  6. "ResourceGroupName": "rg-eun-h1s01-dev-iac",
  7. "Name": "ase-eun-h1s01-dev-iac"
  8. }
  9. }
  10. }

带证书的 App Service Json

  1. "functionAppCustomDomain": {
  2. "value": {
  3. "name": "iac-dev-functionappcustomdomain",
  4. "kind": "functionapp",
  5. "appServiceEnvironment": {
  6. "resourceGroupName": "rg-eun-h1s01-dev-iac",
  7. "name": "ase-eun-h1s01-dev-iac"
  8. },
  9. "customHostnameConfiguration": {
  10. "keyVaultName": "kv-eun-h1s01-dev-odp",
  11. "keyVaultResourceGroup": "rg-eun-h1s01-dev-odp",
  12. "keyVaultCertificateSecretName": "New-Wildcard-Company-com/{HiddenGUID}",
  13. "customHostName": "mytestapp.mycompany.com",
  14. "appServiceCertificateName": "companycert"
  15. }
  16. }
  17. }

Main.bicep

  1. module functionApp 'br/Compute:appservice:v0.1' = {
  2. name: 'functionapp-${basicFunctionAppConfiguration.name}-${uniqueString(basicFunctionAppConfiguration.name)}'
  3. params:{
  4. name: basicFunctionAppConfiguration.name
  5. location: location
  6. appServiceEnvironmentId: resourceId(basicFunctionAppConfiguration.appServiceEnvironment.ResourceGroupName, 'Microsoft.Web/hostingEnvironments', basicFunctionAppConfiguration.appServiceEnvironment.Name)
  7. appServicePlanId: appServicePlan.outputs.resourceId
  8. storageAccountId: resourceId(basicFunctionAppConfiguration.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', basicFunctionAppConfiguration.diagnosticSettings.storageAccount.accountName)
  9. appInsightId: applicationInsights.outputs.resourceId
  10. kind: basicFunctionAppConfiguration.kind
  11. }
  12. }
  13. module functionAppCustomDomainKeyVault 'br/Compute:appservice:v0.1' = {
  14. name: 'functionapp-${functionAppCustomDomain.name}-${uniqueString(functionAppCustomDomain.name)}'
  15. params:{
  16. name: functionAppCustomDomain.name
  17. location: location
  18. appServiceEnvironmentId: resourceId(functionAppCustomDomain.appServiceEnvironment.resourceGroupName, 'Microsoft.Web/hostingEnvironments', functionAppCustomDomain.appServiceEnvironment.name)
  19. appServicePlanId: appServicePlan.outputs.resourceId
  20. storageAccountId: resourceId(functionAppCustomDomain.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', functionAppCustomDomain.diagnosticSettings.storageAccount.accountName)
  21. customHostnameConfiguration: functionAppCustomDomain.customHostnameConfiguration
  22. appInsightId: applicationInsights.outputs.resourceId
  23. kind: functionAppCustomDomain.kind
  24. }
  25. }

App Service bicep

  1. @description('Required. Name of the site.')
  2. param name string
  3. @description('Optional. Location for all Resources.')
  4. param location string = resourceGroup().location
  5. @description('Required. The resource ID of the app service environment to use for this resource.')
  6. param appServiceEnvironmentId string
  7. @description('Required. The resource ID of the app service plan to use for the site.')
  8. param appServicePlanId string
  9. @description('Required. Resource ID of the app insight to leverage for this resource.')
  10. param appInsightId string
  11. @description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
  12. param storageAccountId string
  13. @description('Optional. Resource ID of the diagnostic storage account.')
  14. param diagnosticStorageAccountId string = ''
  15. @description('Optional. Resource ID of log analytics workspace.')
  16. param diagnosticWorkspaceId string = ''
  17. @description('Required. Type of site to deploy.')
  18. @allowed([
  19. 'functionapp' // function app windows os
  20. 'functionapp,linux' // function app linux os
  21. 'functionapp,workflowapp' // logic app workflow
  22. 'functionapp,workflowapp,linux' // logic app docker container
  23. 'app' // normal web app
  24. ])
  25. param kind string
  26. @description('Optional. If client affinity is enabled.')
  27. param clientAffinityEnabled bool = false
  28. @description('Optional. If web sockets are enabled.')
  29. param webSocketsEnabled bool = false
  30. @description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
  31. param appSettingsKeyValuePairs object = {}
  32. @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')
  33. param customHostnameConfiguration object = {}
  34. @description('Optional. Tags of the resource.')
  35. param tags object = {}
  36. //Default Values
  37. var clientCertEnabled = false
  38. var clientCertMode = 'Optional'
  39. var containerSize = -1
  40. var customDomainVerificationId = ''
  41. var dailyMemoryTimeQuota = -1
  42. var enabled = true
  43. var httpsOnly = true
  44. var hyperV = false
  45. 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

  1. "basicFunctionAppConfiguration": {
  2. "value": {
  3. "name": "iac-dev-functionapp",
  4. "kind": "functionapp",
  5. "appServiceEnvironment": {
  6. "ResourceGroupName": "rg-eun-h1s01-dev-iac",
  7. "Name": "ase-eun-h1s01-dev-iac"
  8. }
  9. }
  10. }

App Service with certificate Json

  1. "functionAppCustomDomain": {
  2. "value": {
  3. "name": "iac-dev-functionappcustomdomain",
  4. "kind": "functionapp",
  5. "appServiceEnvironment": {
  6. "resourceGroupName": "rg-eun-h1s01-dev-iac",
  7. "name": "ase-eun-h1s01-dev-iac"
  8. },
  9. "customHostnameConfiguration": {
  10. "keyVaultName": "kv-eun-h1s01-dev-odp",
  11. "keyVaultResourceGroup": "rg-eun-h1s01-dev-odp",
  12. "keyVaultCertificateSecretName": "New-Wildcard-Company-com/{HiddenGUID}",
  13. "customHostName": "mytestapp.mycompany.com",
  14. "appServiceCertificateName": "companycert"
  15. }
  16. }
  17. }

Main.bicep

  1. module functionApp 'br/Compute:appservice:v0.1'= {
  2. name: 'functionapp-${basicFunctionAppConfiguration.name}-${uniqueString(basicFunctionAppConfiguration.name)}'
  3. params:{
  4. name: basicFunctionAppConfiguration.name
  5. location: location
  6. appServiceEnvironmentId: resourceId(basicFunctionAppConfiguration.appServiceEnvironment.ResourceGroupName, 'Microsoft.Web/hostingEnvironments', basicFunctionAppConfiguration.appServiceEnvironment.Name)
  7. appServicePlanId: appServicePlan.outputs.resourceId
  8. storageAccountId: resourceId(basicFunctionAppConfiguration.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', basicFunctionAppConfiguration.diagnosticSettings.storageAccount.accountName)
  9. appInsightId: applicationInsights.outputs.resourceId
  10. kind: basicFunctionAppConfiguration.kind
  11. }
  12. }
  13. module functionAppCustomDomainKeyVault 'br/Compute:appservice:v0.1'= {
  14. name: 'functionapp-${functionAppCustomDomain.name}-${uniqueString(functionAppCustomDomain.name)}'
  15. params:{
  16. name: functionAppCustomDomain.name
  17. location: location
  18. appServiceEnvironmentId: resourceId(functionAppCustomDomain.appServiceEnvironment.resourceGroupName, 'Microsoft.Web/hostingEnvironments', functionAppCustomDomain.appServiceEnvironment.name)
  19. appServicePlanId: appServicePlan.outputs.resourceId
  20. storageAccountId: resourceId(functionAppCustomDomain.diagnosticSettings.storageAccount.resourceGroup, 'Microsoft.Storage/storageAccounts', functionAppCustomDomain.diagnosticSettings.storageAccount.accountName)
  21. customHostnameConfiguration: functionAppCustomDomain.customHostnameConfiguration
  22. appInsightId: applicationInsights.outputs.resourceId
  23. kind: functionAppCustomDomain.kind
  24. }
  25. }

App Service bicep

  1. @description('Required. Name of the site.')
  2. param name string
  3. @description('Optional. Location for all Resources.')
  4. param location string = resourceGroup().location
  5. @description('Required. The resource ID of the app service environment to use for this resource.')
  6. param appServiceEnvironmentId string
  7. @description('Required. The resource ID of the app service plan to use for the site.')
  8. param appServicePlanId string
  9. @description('Required. Resource ID of the app insight to leverage for this resource.')
  10. param appInsightId string
  11. @description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
  12. param storageAccountId string
  13. @description('Optional. Resource ID of the diagnostic storage account.')
  14. param diagnosticStorageAccountId string = ''
  15. @description('Optional. Resource ID of log analytics workspace.')
  16. param diagnosticWorkspaceId string = ''
  17. @description('Required. Type of site to deploy.')
  18. @allowed([
  19. 'functionapp' // function app windows os
  20. 'functionapp,linux' // function app linux os
  21. 'functionapp,workflowapp' // logic app workflow
  22. 'functionapp,workflowapp,linux' // logic app docker container
  23. 'app' // normal web app
  24. ])
  25. param kind string
  26. @description('Optional. If client affinity is enabled.')
  27. param clientAffinityEnabled bool = false
  28. @description('Optional. If web sockets are enabled.')
  29. param webSocketsEnabled bool = false
  30. @description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
  31. param appSettingsKeyValuePairs object = {}
  32. @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')
  33. param customHostnameConfiguration object = {}
  34. @description('Optional. Tags of the resource.')
  35. param tags object = {}
  36. //Default Values
  37. var clientCertEnabled = false
  38. var clientCertMode = 'Optional'
  39. var containerSize = -1
  40. var customDomainVerificationId = ''
  41. var dailyMemoryTimeQuota = -1
  42. var enabled = true
  43. var httpsOnly = true
  44. var hyperV = false
  45. var keyVaultAccessIdentityResourceId = 'SystemAssigned'
  46. var redundancyMode = 'None'
  47. var storageAccountRequired = true
  48. var systemAssignedIdentity = true
  49. // var clientCertExclusionPaths = ''
  50. // var cloningInfo = {}
  51. // var virtualNetworkSubnetId = ''
  52. var defaultAppSettings = {
  53. FUNCTIONS_EXTENSION_VERSION: '~4'
  54. FUNCTIONS_WORKER_RUNTIME: 'dotnet'
  55. }
  56. var completeAppSettings = union(defaultAppSettings, appSettingsKeyValuePairs)
  57. var siteConfig = {
  58. ftpsState: 'FtpsOnly'
  59. minTlsVersion: '1.2'
  60. netFrameworkVersion: '6.0'
  61. alwaysOn: true
  62. autoHealEnabled: true
  63. http20Enabled: true
  64. webSocketsEnabled: webSocketsEnabled
  65. }
  66. //Diagnostics
  67. var diagnosticLogsRetentionInDays = 365
  68. var diagnosticSettingsName = 'diag-${name}-appservice-log'
  69. var diagnosticMetricsToEnable = ['AllMetrics']
  70. var diagnosticLogCategoriesToEnable = contains(kind, 'workflowapp') ? [
  71. 'WorkflowRuntime'
  72. 'FunctionAppLogs'
  73. ] : kind == 'functionapp' ? [
  74. 'FunctionAppLogs'
  75. ] : [
  76. 'AppServiceHTTPLogs'
  77. 'AppServiceConsoleLogs'
  78. 'AppServiceAppLogs'
  79. 'AppServiceAuditLogs'
  80. 'AppServiceIPSecAuditLogs'
  81. 'AppServicePlatformLogs'
  82. ]
  83. var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
  84. category: category
  85. enabled: true
  86. retentionPolicy: {
  87. enabled: true
  88. days: diagnosticLogsRetentionInDays
  89. }
  90. }]
  91. var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
  92. {
  93. categoryGroup: 'allLogs'
  94. enabled: true
  95. retentionPolicy: {
  96. enabled: true
  97. days: diagnosticLogsRetentionInDays
  98. }
  99. }
  100. ] : diagnosticsLogsSpecified
  101. var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
  102. category: metric
  103. timeGrain: null
  104. enabled: true
  105. retentionPolicy: {
  106. enabled: true
  107. days: diagnosticLogsRetentionInDays
  108. }
  109. }]
  110. //Identity
  111. var identityType = systemAssignedIdentity ? 'SystemAssigned' : 'None'
  112. var identity = identityType != 'None' ? {
  113. type: identityType
  114. userAssignedIdentities: null
  115. } : null
  116. //Telemetry
  117. var enableDefaultTelemetry = true
  118. resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
  119. name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}'
  120. properties: {
  121. mode: 'Incremental'
  122. template: {
  123. '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
  124. contentVersion: '1.0.0.0'
  125. resources: []
  126. }
  127. }
  128. }
  129. //KeyVault Certificate
  130. resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = if (!empty(customHostnameConfiguration)) {
  131. name: contains(customHostnameConfiguration, 'appServiceCertificateName') ? customHostnameConfiguration.appServiceCertificateName : ''
  132. location: location
  133. properties: {
  134. keyVaultId: resourceId(customHostnameConfiguration.keyVaultResourceGroup, 'Microsoft.KeyVault/vaults', customHostnameConfiguration.keyVaultName)
  135. keyVaultSecretName: contains(customHostnameConfiguration, 'keyVaultCertificateSecretName') ? customHostnameConfiguration.keyVaultCertificateSecretName : ''
  136. serverFarmId: appServicePlanId
  137. }
  138. }
  139. //Create the app service
  140. resource app 'Microsoft.Web/sites@2021-03-01' = {
  141. name: name
  142. location: location
  143. kind: kind
  144. tags: tags
  145. identity: identity
  146. properties: {
  147. serverFarmId: appServicePlanId
  148. clientAffinityEnabled: clientAffinityEnabled
  149. httpsOnly: httpsOnly
  150. hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? {
  151. id: appServiceEnvironmentId
  152. } : null
  153. storageAccountRequired: storageAccountRequired
  154. keyVaultReferenceIdentity: !empty(keyVaultAccessIdentityResourceId) ? keyVaultAccessIdentityResourceId : null
  155. siteConfig: siteConfig
  156. clientCertEnabled: clientCertEnabled
  157. clientCertMode: clientCertMode
  158. containerSize: containerSize != -1 ? containerSize : null
  159. customDomainVerificationId: !empty(customDomainVerificationId) ? customDomainVerificationId : null
  160. dailyMemoryTimeQuota: dailyMemoryTimeQuota != -1 ? dailyMemoryTimeQuota : null
  161. enabled: enabled
  162. hostNamesDisabled: false
  163. hyperV: hyperV
  164. redundancyMode: redundancyMode
  165. }
  166. }
  167. // hostNameSslStates: (!empty(customHostnameConfiguration)) ? customHostnameState : null
  168. //cloningInfo: !empty(cloningInfo) ? cloningInfo : null
  169. //virtualNetworkSubnetId: !empty(virtualNetworkSubnetId) ? virtualNetworkSubnetId : any(null)
  170. //clientCertExclusionPaths: !empty(clientCertExclusionPaths) ? clientCertExclusionPaths : null
  171. resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = if (!empty(customHostnameConfiguration)) {
  172. name: contains(customHostnameConfiguration, 'customHostName') ? customHostnameConfiguration.customHostName : '${uniqueString(deployment().name, location)}-hostnamebinding'
  173. parent: app
  174. properties: {
  175. siteName: contains(customHostnameConfiguration, 'customHostName') ? customHostnameConfiguration.customHostName : ''
  176. sslState: 'SniEnabled'
  177. thumbprint: !empty(appServiceCertificate) ? appServiceCertificate.properties.thumbprint : ''
  178. }
  179. }
  180. //Set the default stack to dotnet
  181. resource appSettingsStack 'Microsoft.Web/sites/config@2021-03-01' = {
  182. name: 'metadata'
  183. parent: app
  184. properties: {
  185. CURRENT_STACK: 'dotnet'
  186. }
  187. }
  188. //Save the app settings
  189. module app_appsettings 'br/Compute:appservice/appsettings:v0.1' = if (!empty(completeAppSettings)) {
  190. name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings'
  191. params: {
  192. appName: app.name
  193. kind: kind
  194. storageAccountId: storageAccountId
  195. appInsightId: appInsightId
  196. appSettingsKeyValuePairs: completeAppSettings
  197. }
  198. }
  199. //Diagnostics
  200. resource app_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId)) {
  201. name: !empty(diagnosticSettingsName) ? diagnosticSettingsName : '${name}-diagnosticSettings'
  202. properties: {
  203. storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
  204. workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
  205. metrics: diagnosticsMetrics
  206. logs: diagnosticsLogs
  207. }
  208. scope: app
  209. }
  210. // Outputs
  211. @description('The name of the site.')
  212. output name string = app.name
  213. @description('The resource ID of the site.')
  214. output appServiceResourceId string = app.id
  215. @description('The resource group the site was deployed into.')
  216. output resourceGroupName string = resourceGroup().name
  217. @description('The principal ID of the system assigned identity.')
  218. output systemAssignedPrincipalId string = systemAssignedIdentity && contains(app.identity, 'principalId') ? app.identity.principalId : ''
  219. @description('The location the resource was deployed into.')
  220. output location string = app.location
  221. @description('Default hostname of the app.')
  222. output defaultHostname string = app.properties.defaultHostName

答案1

得分: 0

  1. 所以,答案是你必须为证书和主机名绑定创建一个子模块才能使其工作。
  2. **AppService.bicep**
  3. @param name string
  4. @description('Required. Name of the site.')
  5. ...
  6. ...
  7. // Default Values
  8. ...
  9. ...
  10. // var clientCertExclusionPaths = ''
  11. // var cloningInfo = {}
  12. // var virtualNetworkSubnetId = ''
  13. ...
  14. // Outputs
  15. ...
  16. ...
  17. **AppServiceCertificate.bicep**
  18. @param appServiceName string
  19. @description('Required. Name of the app service to bind the key vault certificate.')
  20. ...
  21. ...
  22. resource appService 'Microsoft.Web/sites@2021-03-01' existing = {
  23. name: appServiceName
  24. }
  25. resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = {
  26. name: appServiceCertificateName
  27. ...
  28. }
  29. resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = {
  30. ...
  31. }
英文:

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

  1. @description('Required. Name of the site.')
  2. param name string
  3. @description('Optional. Location for all Resources.')
  4. param location string = resourceGroup().location
  5. @description('Required. The resource ID of the app service environment to use for this resource.')
  6. param appServiceEnvironmentId string
  7. @description('Required. The resource ID of the app service plan to use for the site.')
  8. param appServicePlanId string
  9. @description('Required. Resource ID of the app insight to leverage for this resource.')
  10. param appInsightId string
  11. @description('Required. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.')
  12. param storageAccountId string
  13. @description('Optional. Resource ID of the diagnostic storage account.')
  14. param diagnosticStorageAccountId string = ''
  15. @description('Optional. Resource ID of log analytics workspace.')
  16. param diagnosticWorkspaceId string = ''
  17. @description('Required. Type of site to deploy.')
  18. @allowed([
  19. 'functionapp' // function app windows os
  20. 'functionapp,linux' // function app linux os
  21. 'functionapp,workflowapp' // logic app workflow
  22. 'functionapp,workflowapp,linux' // logic app docker container
  23. 'app' // normal web app
  24. ])
  25. param kind string
  26. @description('Optional. If client affinity is enabled.')
  27. param clientAffinityEnabled bool = false
  28. @description('Optional. If web sockets are enabled.')
  29. param webSocketsEnabled bool = false
  30. @description('Optional. The app settings-value pairs except for AzureWebJobsStorage, AzureWebJobsDashboard, APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING.')
  31. param appSettingsKeyValuePairs object = {}
  32. @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')
  33. param customHostnameConfiguration object = {}
  34. @description('Optional. Tags of the resource.')
  35. param tags object = {}
  36. //Default Values
  37. var clientCertEnabled = false
  38. var clientCertMode = 'Optional'
  39. var containerSize = -1
  40. var customDomainVerificationId = ''
  41. var dailyMemoryTimeQuota = -1
  42. var enabled = true
  43. var httpsOnly = true
  44. var hyperV = false
  45. var keyVaultAccessIdentityResourceId = 'SystemAssigned'
  46. var redundancyMode = 'None'
  47. var storageAccountRequired = true
  48. var systemAssignedIdentity = true
  49. // var clientCertExclusionPaths = ''
  50. // var cloningInfo = {}
  51. // var virtualNetworkSubnetId = ''
  52. var defaultAppSettings = {
  53. FUNCTIONS_EXTENSION_VERSION: '~4'
  54. FUNCTIONS_WORKER_RUNTIME: 'dotnet'
  55. }
  56. var completeAppSettings = union(defaultAppSettings, appSettingsKeyValuePairs)
  57. var siteConfig = {
  58. ftpsState: 'FtpsOnly'
  59. minTlsVersion: '1.2'
  60. netFrameworkVersion: '6.0'
  61. alwaysOn: true
  62. autoHealEnabled: true
  63. http20Enabled: true
  64. webSocketsEnabled: webSocketsEnabled
  65. }
  66. //Diagnostics
  67. var diagnosticLogsRetentionInDays = 365
  68. var diagnosticSettingsName = 'diag-${name}-appservice-log'
  69. var diagnosticMetricsToEnable = ['AllMetrics']
  70. var diagnosticLogCategoriesToEnable = contains(kind, 'workflowapp') ? [
  71. 'WorkflowRuntime'
  72. 'FunctionAppLogs'
  73. ] : kind == 'functionapp' ? [
  74. 'FunctionAppLogs'
  75. ] : [
  76. 'AppServiceHTTPLogs'
  77. 'AppServiceConsoleLogs'
  78. 'AppServiceAppLogs'
  79. 'AppServiceAuditLogs'
  80. 'AppServiceIPSecAuditLogs'
  81. 'AppServicePlatformLogs'
  82. ]
  83. var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
  84. category: category
  85. enabled: true
  86. retentionPolicy: {
  87. enabled: true
  88. days: diagnosticLogsRetentionInDays
  89. }
  90. }]
  91. var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
  92. {
  93. categoryGroup: 'allLogs'
  94. enabled: true
  95. retentionPolicy: {
  96. enabled: true
  97. days: diagnosticLogsRetentionInDays
  98. }
  99. }
  100. ] : diagnosticsLogsSpecified
  101. var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
  102. category: metric
  103. timeGrain: null
  104. enabled: true
  105. retentionPolicy: {
  106. enabled: true
  107. days: diagnosticLogsRetentionInDays
  108. }
  109. }]
  110. //Identity
  111. var identityType = systemAssignedIdentity ? 'SystemAssigned' : 'None'
  112. var identity = identityType != 'None' ? {
  113. type: identityType
  114. userAssignedIdentities: null
  115. } : null
  116. //Telemetry
  117. var enableDefaultTelemetry = true
  118. resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
  119. name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}'
  120. properties: {
  121. mode: 'Incremental'
  122. template: {
  123. '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
  124. contentVersion: '1.0.0.0'
  125. resources: []
  126. }
  127. }
  128. }
  129. //Create the app service
  130. resource app 'Microsoft.Web/sites@2021-03-01' = {
  131. name: name
  132. location: location
  133. kind: kind
  134. tags: tags
  135. identity: identity
  136. properties: {
  137. serverFarmId: appServicePlanId
  138. clientAffinityEnabled: clientAffinityEnabled
  139. httpsOnly: httpsOnly
  140. hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? {
  141. id: appServiceEnvironmentId
  142. } : null
  143. storageAccountRequired: storageAccountRequired
  144. keyVaultReferenceIdentity: !empty(keyVaultAccessIdentityResourceId) ? keyVaultAccessIdentityResourceId : null
  145. siteConfig: siteConfig
  146. clientCertEnabled: clientCertEnabled
  147. clientCertMode: clientCertMode
  148. containerSize: containerSize != -1 ? containerSize : null
  149. customDomainVerificationId: !empty(customDomainVerificationId) ? customDomainVerificationId : null
  150. dailyMemoryTimeQuota: dailyMemoryTimeQuota != -1 ? dailyMemoryTimeQuota : null
  151. enabled: enabled
  152. hostNamesDisabled: false
  153. hyperV: hyperV
  154. redundancyMode: redundancyMode
  155. }
  156. }
  157. // hostNameSslStates: (!empty(customHostnameConfiguration)) ? customHostnameState : null
  158. //cloningInfo: !empty(cloningInfo) ? cloningInfo : null
  159. //virtualNetworkSubnetId: !empty(virtualNetworkSubnetId) ? virtualNetworkSubnetId : any(null)
  160. //clientCertExclusionPaths: !empty(clientCertExclusionPaths) ? clientCertExclusionPaths : null
  161. module appServiceCertificate 'br/Compute:appservice/appservicecertificates:v0.1' = if (!empty(customHostnameConfiguration)) {
  162. name: '${uniqueString(deployment().name, location)}-app-service-certificate'
  163. dependsOn: [app]
  164. params:{
  165. appServiceName: name
  166. appServicePlanId: appServicePlanId
  167. keyVaultName: customHostnameConfiguration.keyVaultName
  168. keyVaultResourceGroup: customHostnameConfiguration.keyVaultResourceGroup
  169. keyVaultCertificateSecretName: customHostnameConfiguration.keyVaultCertificateSecretName
  170. customHostName: customHostnameConfiguration.customHostName
  171. appServiceCertificateName: customHostnameConfiguration.appServiceCertificateName
  172. }
  173. }
  174. //Set the default stack to dotnet
  175. resource appSettingsStack 'Microsoft.Web/sites/config@2021-03-01' = {
  176. name: 'metadata'
  177. parent: app
  178. properties: {
  179. CURRENT_STACK: 'dotnet'
  180. }
  181. }
  182. //Save the app settings
  183. module app_appsettings 'br/Compute:appservice/appsettings:v0.1' = if (!empty(completeAppSettings)) {
  184. name: '${uniqueString(deployment().name, location)}-Site-Config-AppSettings'
  185. params: {
  186. appName: app.name
  187. kind: kind
  188. storageAccountId: storageAccountId
  189. appInsightId: appInsightId
  190. appSettingsKeyValuePairs: completeAppSettings
  191. }
  192. }
  193. //Diagnostics
  194. resource app_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId)) {
  195. name: !empty(diagnosticSettingsName) ? diagnosticSettingsName : '${name}-diagnosticSettings'
  196. properties: {
  197. storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
  198. workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
  199. metrics: diagnosticsMetrics
  200. logs: diagnosticsLogs
  201. }
  202. scope: app
  203. }
  204. // Outputs
  205. @description('The name of the site.')
  206. output name string = app.name
  207. @description('The resource ID of the site.')
  208. output appServiceResourceId string = app.id
  209. @description('The resource group the site was deployed into.')
  210. output resourceGroupName string = resourceGroup().name
  211. @description('The principal ID of the system assigned identity.')
  212. output systemAssignedPrincipalId string = systemAssignedIdentity && contains(app.identity, 'principalId') ? app.identity.principalId : ''
  213. @description('The location the resource was deployed into.')
  214. output location string = app.location
  215. @description('Default hostname of the app.')
  216. output defaultHostname string = app.properties.defaultHostName

AppServiceCertificate.bicep

  1. @description('Required. Name of the app service to bind the key vault certificate.')
  2. param appServiceName string
  3. @description('Required. Resource Id of the app service plan.')
  4. param appServicePlanId string
  5. @description('Optional. Location for all Resources.')
  6. param location string = resourceGroup().location
  7. @description('Required. Name of the keyvault where the certificate is stored.')
  8. param keyVaultName string
  9. @description('Required. Name of the keyvault resource group where the certificate is stored.')
  10. param keyVaultResourceGroup string
  11. @description('Required. Name of the keyvault certificate including version in {keyvaultname}/{version} format')
  12. param keyVaultCertificateSecretName string
  13. @description('Required. Custom hostname for the app service')
  14. param customHostName string
  15. @description('Required. Certificate name for this app service. This is registered against the resource group')
  16. param appServiceCertificateName string
  17. resource appService 'Microsoft.Web/sites@2021-03-01' existing = {
  18. name: appServiceName
  19. }
  20. resource appServiceCertificate 'Microsoft.Web/certificates@2022-03-01' = {
  21. name: appServiceCertificateName
  22. location: location
  23. properties: {
  24. keyVaultId: resourceId(keyVaultResourceGroup, 'Microsoft.KeyVault/vaults', keyVaultName)
  25. keyVaultSecretName: keyVaultCertificateSecretName
  26. serverFarmId: appServicePlanId
  27. }
  28. }
  29. resource hostNameBinding 'Microsoft.Web/sites/hostNameBindings@2021-03-01' = {
  30. name: customHostName
  31. parent: appService
  32. properties: {
  33. siteName: customHostName
  34. sslState: 'SniEnabled'
  35. thumbprint: !empty(appServiceCertificate) ? appServiceCertificate.properties.thumbprint : ''
  36. }
  37. }

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:

确定