优化Azure Front Door经典版Bicep模板,支持多动态配置
改进Front Door经典版Bicep模块以支持动态配置
需求背景
我有一个作为共享模块使用的Bicep仓库,其中的Front Door(经典版)模板需要支持动态传入多个自定义域名、后端池和路由规则,方便不同应用复用,避免硬编码配置。
原始模板与调用代码
原始Front Door模块
param frontDoorName string param backEndAddress string param frontEndEndPointName string param backEndPoolName string var loadBalancingSettingsName = '' var healthProbeSettingsName = '' var routingRuleName = '' resource myFrontDoorResource 'Microsoft.Network/frontDoors@2021-06-01' = { name: frontDoorName location: 'global' properties: { enabledState: 'Enabled' frontendEndpoints: [ { name: frontEndEndPointName properties: { hostName: '${frontDoorName}.azurefd.net' sessionAffinityEnabledState: 'Disabled' } } ] loadBalancingSettings: [ { name: loadBalancingSettingsName properties: { sampleSize: 4 successfulSamplesRequired: 2 } } ] healthProbeSettings: [ { name: healthProbeSettingsName properties: { path: '/' protocol: 'Http' intervalInSeconds: 120 } } ] backendPools: [ { name: backEndPoolName properties: { backends: [ { address: backEndAddress backendHostHeader: backEndAddress httpPort: 80 httpsPort: 443 weight: 100 priority: 1 enabledState: 'Enabled' } ] loadBalancingSettings: { id: resourceId('Microsoft.Network/frontDoors/loadBalancingSettings', frontDoorName, loadBalancingSettingsName) } healthProbeSettings: { id: resourceId('Microsoft.Network/frontDoors/healthProbeSettings', frontDoorName, healthProbeSettingsName) } } } ] routingRules: [ { name: routingRuleName properties: { frontendEndpoints: [ { id: resourceId('Microsoft.Network/frontDoors/frontEndEndpoints', frontDoorName, frontEndEndPointName) } ] acceptedProtocols: [ 'Http' 'Https' ] patternsToMatch: [ '/*' ] routeConfiguration: { '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' forwardingProtocol: 'MatchRequest' backendPool: { id: resourceId('Microsoft.Network/frontDoors/backEndPools', frontDoorName, backEndPoolName) } } enabledState: 'Enabled' } } ] } }
原始模块调用代码
module myFrontDoorModule 'azurefrontdoor.bicep' = { name: '' params: { frontDoorName: '' backEndAddress: '' frontEndEndpPintName: '' backEndPoolName: '' } }
初步改造尝试
我已经尝试将硬编码的配置改为数组形式,但目前还是用var定义死了内容,需要改成可通过参数传入的形式:
param frontDoorName string var loadBalancingSettingsName = 'loadBalancingSettings' var healthProbeSettingsName = 'healthProbeSettings' var endpoints = [ { name: 'frontEndEndpoint' hostName: '${frontDoorName}.azurefd.net' } { name: 'abc' hostName: 'abc.com' } { name: 'xyz' hostName: 'xyz.com' } ] var backendPoolArray = [ { backendPoolName: 'firstbepool' backendAddress: 'abc.azurewebsites.net' } { backendPoolName: 'secondbepool' backendAddress: 'xyz.azurewebsites.net' } ] var routingRules = [ { routingRuleName: 'routingRuleOne' backendPoolName: 'firstbepool' endpointName: 'abc' } { routingRuleName: 'routingRuleTwo' backendPoolName: 'secondbepool' endpointName: 'xyz' } ] resource frontDoorResource 'Microsoft.Network/frontDoors@2021-06-01' = { name: frontDoorName location: 'global' properties: { enabledState: 'Enabled' frontendEndpoints: [for endpoint in endpoints: { name: endpoint.name properties: { hostName: endpoint.hostName sessionAffinityEnabledState: 'Disabled' } }] loadBalancingSettings: [ { name: loadBalancingSettingsName properties: { sampleSize: 4 successfulSamplesRequired: 2 } } ] healthProbeSettings: [ { name: healthProbeSettingsName properties: { path: '/' protocol: 'Http' intervalInSeconds: 120 } } ] backendPools: [for backendPool in backendPoolArray: { name: backendPool.backendPoolName properties: { backends: [ { address: backendPool.backendAddress backendHostHeader: backendPool.backendAddress httpPort: 80 httpsPort: 443 weight: 100 priority: 1 enabledState: 'Enabled' } ] loadBalancingSettings: { id: resourceId('Microsoft.Network/frontDoors/loadBalancingSettings', frontDoorName, loadBalancingSettingsName) } healthProbeSettings: { id: resourceId('Microsoft.Network/frontDoors/healthProbeSettings', frontDoorName, healthProbeSettingsName) } } }] routingRules: [for routingRule in routingRules: { name: routingRule.routingRuleName properties: { frontendEndpoints: [ { id: resourceId('Microsoft.Network/frontDoors/frontEndEndpoints', frontDoorName, routingRule.endpointName) } ] acceptedProtocols: [ 'Http' 'Https' ] patternsToMatch: [ '/*' ] routeConfiguration: { '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' forwardingProtocol: 'MatchRequest' backendPool: { id: resourceId('Microsoft.Network/frontDoors/backEndPools', frontDoorName, routingRule.backendPoolName) } } enabledState: 'Enabled' } }] } }
最终改进方案
将模块改为通过参数数组接收配置,同时保留默认的Front Door原生域名(${frontDoorName}.azurefd.net),让调用方可以灵活添加自定义配置:
改进后的Front Door模块
param frontDoorName string // 定义自定义类型,提升参数可读性和类型校验 type FrontendEndpoint = { name: string hostName: string sessionAffinityEnabledState?: string // 可选参数,默认Disabled } type BackendPoolConfig = { backendPoolName: string backendAddress: string backendHostHeader?: string // 可选,默认与backendAddress一致 httpPort?: int // 可选,默认80 httpsPort?: int // 可选,默认443 weight?: int // 可选,默认100 priority?: int // 可选,默认1 } type RoutingRuleConfig = { routingRuleName: string backendPoolName: string endpointNames: string[] // 支持绑定多个端点 acceptedProtocols?: string[] // 可选,默认["Http", "Https"] patternsToMatch?: string[] // 可选,默认["/*"] } // 默认配置:FrontDoor原生域名 param defaultFrontendEndpointName string = 'defaultEndpoint' param customFrontendEndpoints array = [] // 合并默认端点和自定义端点 var allFrontendEndpoints = concat([ { name: defaultFrontendEndpointName hostName: '${frontDoorName}.azurefd.net' sessionAffinityEnabledState: 'Disabled' } ], customFrontendEndpoints) // 后端池参数数组 param backendPools array = [] // 路由规则参数数组 param routingRules array = [] // 固定的负载均衡和健康探测配置(如需动态可改为参数) var loadBalancingSettingsName = 'defaultLoadBalancing' var healthProbeSettingsName = 'defaultHealthProbe' resource frontDoorResource 'Microsoft.Network/frontDoors@2021-06-01' = { name: frontDoorName location: 'global' properties: { enabledState: 'Enabled' frontendEndpoints: [for endpoint in allFrontendEndpoints: { name: endpoint.name properties: { hostName: endpoint.hostName sessionAffinityEnabledState: endpoint.sessionAffinityEnabledState ?? 'Disabled' } }] loadBalancingSettings: [ { name: loadBalancingSettingsName properties: { sampleSize: 4 successfulSamplesRequired: 2 } } ] healthProbeSettings: [ { name: healthProbeSettingsName properties: { path: '/' protocol: 'Http' intervalInSeconds: 120 } } ] backendPools: [for pool in backendPools: { name: pool.backendPoolName properties: { backends: [ { address: pool.backendAddress backendHostHeader: pool.backendHostHeader ?? pool.backendAddress httpPort: pool.httpPort ?? 80 httpsPort: pool.httpsPort ?? 443 weight: pool.weight ?? 100 priority: pool.priority ?? 1 enabledState: 'Enabled' } ] loadBalancingSettings: { id: resourceId('Microsoft.Network/frontDoors/loadBalancingSettings', frontDoorName, loadBalancingSettingsName) } healthProbeSettings: { id: resourceId('Microsoft.Network/frontDoors/healthProbeSettings', frontDoorName, healthProbeSettingsName) } } }] routingRules: [for rule in routingRules: { name: rule.routingRuleName properties: { frontendEndpoints: [for endpointName in rule.endpointNames: { id: resourceId('Microsoft.Network/frontDoors/frontEndEndpoints', frontDoorName, endpointName) }] acceptedProtocols: rule.acceptedProtocols ?? ['Http', 'Https'] patternsToMatch: rule.patternsToMatch ?? ['/*'] routeConfiguration: { '@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration' forwardingProtocol: 'MatchRequest' backendPool: { id: resourceId('Microsoft.Network/frontDoors/backEndPools', frontDoorName, rule.backendPoolName) } } enabledState: 'Enabled' } }] } }
调用示例
module myFrontDoorModule 'azurefrontdoor.bicep' = { name: 'deployFrontDoor' params: { frontDoorName: 'myCustomFrontDoor' customFrontendEndpoints: [ { name: 'abcEndpoint' hostName: 'abc.com' } { name: 'xyzEndpoint' hostName: 'xyz.com' } ] backendPools: [ { backendPoolName: 'abcBackendPool' backendAddress: 'abc.azurewebsites.net' } { backendPoolName: 'xyzBackendPool' backendAddress: 'xyz.azurewebsites.net' weight: 50 } ] routingRules: [ { routingRuleName: 'abcRoute' backendPoolName: 'abcBackendPool' endpointNames: ['abcEndpoint'] } { routingRuleName: 'xyzRoute' backendPoolName: 'xyzBackendPool' endpointNames: ['xyzEndpoint'] patternsToMatch: ['/api/*'] } ] } }
关键改进点
- 自定义类型定义:通过
type关键字定义配置结构,提升参数的可读性和类型校验能力,避免调用时传参错误。 - 参数化数组:将原本硬编码的端点、后端池、路由规则改为
param数组,调用方可以根据需求传入任意数量的配置。 - 默认配置兼容:自动包含Front Door原生域名作为默认端点,无需调用方额外配置,同时支持添加自定义域名。
- 可选参数支持:为非必填字段设置默认值,简化调用时的传参逻辑。
- 灵活的路由绑定:路由规则支持绑定多个前端端点,满足复杂场景需求。
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

