You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化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/*']
      }
    ]
  }
}

关键改进点

  1. 自定义类型定义:通过type关键字定义配置结构,提升参数的可读性和类型校验能力,避免调用时传参错误。
  2. 参数化数组:将原本硬编码的端点、后端池、路由规则改为param数组,调用方可以根据需求传入任意数量的配置。
  3. 默认配置兼容:自动包含Front Door原生域名作为默认端点,无需调用方额外配置,同时支持添加自定义域名。
  4. 可选参数支持:为非必填字段设置默认值,简化调用时的传参逻辑。
  5. 灵活的路由绑定:路由规则支持绑定多个前端端点,满足复杂场景需求。

内容的提问来源于stack exchange,提问作者Lucky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:27:04