我在 Bicep 中遇到了这个奇怪的问题,当我尝试为 Azure Front Door 部署安全策略时,它在定义自定义域时有效,但当未定义自定义域并尝试使用前门端点时,它会抛出以下错误。使用 FrontDoor 端点 ID 关联到安全策略时,尝试引用 FrontDoor 时似乎存在一些验证问题。
"message": "部署模板验证失败:'资源 模板中未定义“Microsoft.Cdn/profiles/afd-test”。 请参阅https://aka.ms/arm-syntax了解使用详情。'。”
主要.二头肌
module azureFrontDoor 'FrontDoorEndpoint.bicep' = {
name: 'azureFrontDoor${frontDoorProfileName}'
scope: resourceGroup(SharedResourceGroup)
params: {
frontDoorProfileName: frontDoorProfileName
endpointName: frontDoorEndpointName
wafRateLimitThreshold: wafRateLimitThreshold
}
}
WafPolicy.bicep
param wafManagedRuleSets array = [
{
ruleSetType: 'Microsoft_DefaultRuleSet'
ruleSetVersion: '2.1'
ruleSetAction: 'Block'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '1.0'
}
]
var wafRateLimitRuleForDDoSCustomRuleSet = [
{
action: 'Block'
enabledState: 'Enabled'
matchConditions: [
{
matchValue: [
'::/0'
]
matchVariable: 'SocketAddr'
negateCondition: false
operator: 'IPMatch'
}
]
name: 'RateLimitRuleForDDoS'
priority: 100
rateLimitDurationInMinutes: 5
rateLimitThreshold: wafRateLimitThreshold
ruleType: 'RateLimitRule'
}
]
resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' = {
name: wadPolicyName
location: 'global'
sku: {
name: skuName
}
properties: {
policySettings: {
enabledState: 'Enabled'
mode: wafMode
}
managedRules: {
managedRuleSets: wafManagedRuleSets
}
customRules: {
rules: empty(wafCustomRuleSets) ? wafRateLimitRuleForDDoSCustomRuleSet : concat(wafRateLimitRuleForDDoSCustomRuleSet, wafCustomRuleSets)
}
}
}
output wafPolicyId string = wafPolicy.id
FrontDooEndpoint.bicep
resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = {
name: frontDoorProfileName
}
resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' existing = if (wafPolicyName != '') {
name: wafPolicyName
scope: resourceGroup(wafPolicyResourceGroup)
}
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = if(!empty(keyVaultName)) {
name: keyVaultName
scope: resourceGroup(keyVaultRG)
}
resource frontDoorEndpoint 'Microsoft.Cdn/profiles/afdEndpoints@2023-05-01' = {
name: endpointName
parent: frontDoorProfile
location: 'global'
properties: {
autoGeneratedDomainNameLabelScope: 'SubscriptionReuse'
enabledState: 'Enabled'
}
}
module wafPolicyModule './WafPolicy.bicep' = if(empty(wafPolicyName)) {
name: 'wafPolicy'
params: {
wadPolicyName: replace('WAF${endpointName}', '-', '')
wafRateLimitThreshold: wafRateLimitThreshold
skuName: skuName
wafMode: wafMode
wafCustomRuleSets: wafCustomRuleSets
}
}
resource secret 'Microsoft.Cdn/profiles/secrets@2023-05-01' = if(!empty(customDomainName)) {
parent: frontDoorProfile
name: certificateName
properties: {
parameters: {
type: 'CustomerCertificate'
useLatestVersion: true
secretSource: {
id: '${keyVault.id}/secrets/${certificateName}'
}
}
}
}
resource customDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = if(!empty(customDomainName)) {
parent: frontDoorProfile
name: replace(replace(customDomainName, '.', '-'), '-', '')
properties: {
hostName: customDomainName
tlsSettings: {
certificateType: 'CustomerCertificate'
minimumTlsVersion: 'TLS12'
secret: {
id: secret.id
}
}
}
}
resource securityPolicy 'Microsoft.Cdn/profiles/securityPolicies@2023-05-01' = {
name: replace('Security${endpointName}', '-', '')
parent: frontDoorProfile
properties: {
parameters: {
type: 'WebApplicationFirewall'
wafPolicy: {
id: !empty(wafPolicyName) ? wafPolicy.id : wafPolicyModule.outputs.wafPolicyId
}
associations: [
{
domains: [
{
id: !empty(customDomainName) ? customDomain.id : frontDoorEndpoint.id
}
]
patternsToMatch: [
'/*'
]
}
]
}
}
}
此部署的主要问题是
empty
“检查”。
即使设置了条件,资源名称也不能为空,因为 ARM 会检查资源 id 中的数字段。
这会引发错误:
resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = if (!empty(frontDoorProfileName)) {
name: frontDoorProfileName
}
这不会
resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = if (!empty(frontDoorProfileName)) {
name: !empty(frontDoorProfileName) ? frontDoorProfileName : 'notapplicable'
}
我创建了一个
CustomDomain.bicep
模块,仅在需要自定义域时执行:
param keyVaultRG string
param keyVaultName string
param frontDoorProfileName string
param customDomainName string
param certificateName string
// Return custom domain id
output id string = customDomain.id
// Get a reference to the existing front door
resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = {
name: frontDoorProfileName
}
// Get a ference to existing key vault
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
name: keyVaultName
scope: resourceGroup(keyVaultRG)
}
// Create the secret
resource secret 'Microsoft.Cdn/profiles/secrets@2023-05-01' = {
parent: frontDoorProfile
name: certificateName
properties: {
parameters: {
type: 'CustomerCertificate'
useLatestVersion: true
secretSource: {
id: '${keyVault.id}/secrets/${certificateName}'
}
}
}
}
// Create the custom domain
resource customDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = {
parent: frontDoorProfile
name: replace(replace(customDomainName, '.', '-'), '-', '')
properties: {
hostName: customDomainName
tlsSettings: {
certificateType: 'CustomerCertificate'
minimumTlsVersion: 'TLS12'
secret: {
id: secret.id
}
}
}
}
FrontDoorEndpoint.bicep
模块看起来像这样:
param frontDoorProfileName string
param wafPolicyName string = ''
param wafPolicyResourceGroup string = ''
param keyVaultName string = ''
param keyVaultRG string = ''
param endpointName string
param customDomainName string = ''
param certificateName string = ''
param wafRateLimitThreshold int
param skuName string = 'Premium_AzureFrontDoor'
param wafMode string = 'Detection'
param wafCustomRuleSets array = []
// Get a reference to the existing front door
resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = {
name: frontDoorProfileName
}
// Create the endpoint
resource frontDoorEndpoint 'Microsoft.Cdn/profiles/afdEndpoints@2023-05-01' = {
name: endpointName
parent: frontDoorProfile
location: 'global'
properties: {
autoGeneratedDomainNameLabelScope: 'SubscriptionReuse'
enabledState: 'Enabled'
}
}
// If there is an existing waf, use it
resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' existing = if (!empty(wafPolicyName)) {
name: !empty(wafPolicyName) ? wafPolicyName : 'notapplicable'
scope: resourceGroup(wafPolicyResourceGroup)
}
// Otherwise create a new/default one
module wafPolicyModule './WafPolicy.bicep' = if (empty(wafPolicyName)) {
name: 'wafPolicy'
params: {
wadPolicyName: replace('WAF${endpointName}', '-', '')
wafRateLimitThreshold: wafRateLimitThreshold
skuName: skuName
wafMode: wafMode
wafCustomRuleSets: wafCustomRuleSets
}
}
// Create a custom domain if required
var addCustomDomain = !empty(customDomainName) && !empty(certificateName) && !empty(keyVaultRG) && !empty(keyVaultName)
module customDomainModule './CustomDomain.bicep' = if (addCustomDomain) {
name: 'CustomDomain'
params: {
frontDoorProfileName: frontDoorProfile.name
keyVaultRG: keyVaultRG
keyVaultName: keyVaultName
certificateName: certificateName
customDomainName: customDomainName
}
}
// Create the security policy
resource securityPolicy 'Microsoft.Cdn/profiles/securityPolicies@2023-05-01' = {
name: replace('Security${endpointName}', '-', '')
parent: frontDoorProfile
properties: {
parameters: {
type: 'WebApplicationFirewall'
wafPolicy: {
id: !empty(wafPolicyName) ? wafPolicy.id : wafPolicyModule.outputs.wafPolicyId
}
associations: [
{
domains: [
{
id: addCustomDomain ? customDomainModule.outputs.id : frontDoorEndpoint.id
}
]
patternsToMatch: [
'/*'
]
}
]
}
}
}
然后从主要部署中调用它,如下所示:
param frontDoorProfileName string = 'fd-thomastest-001'
param SharedResourceGroup string = 'stackoverflow'
param frontDoorEndpointName string = 'fde-thomastest-001'
param wafRateLimitThreshold int = 1000
module azureFrontDoor 'FrontDoorEndpoint.bicep' = {
name: 'azureFrontDoor${frontDoorProfileName}'
scope: resourceGroup(SharedResourceGroup)
params: {
frontDoorProfileName: frontDoorProfileName
endpointName: frontDoorEndpointName
wafRateLimitThreshold: wafRateLimitThreshold
}
}