Closed robkendrick closed 1 year ago
Update: I actually ended up resolving this by adding a Property Aggregator module. I hate that I had to do this, but for now, it's a cleaner solution than hardcoding/manual iteration on fixed values which would defeat the purpose of a template.
For those interested, here is the updated agPropertyIterator.bicep
file:
// AGPropertyIterator - for generating the iterative properties for each app and/or hostname.
param ruleNumberSeed int = 0 // i*(i+1)*length(app.hostNames) -- This prevents overlapping rule numbers when iterating over iterations.
param app object = {
appName: '(app.appName)'
type: 'web'
domain: '(app.domain)'
hostNames: ['www', 'otherHostName']
instances: 2
probe: '/'
ssl: {
certName: '(app.cert)'
certId: '(Secret URI for certificate in keyVault)'
}
}
param appGatewayName string
param appGatewayId string
var suffix = take(toLower(uniqueString(resourceGroup().id)), 10)
var backendAddresses = [for i in range(1, app.instances): {
fqdn: i < 10 ? '${app.appName}0${i}${app.type}${suffix}.azurewebsites.net' : '${app.appName}${i}${app.type}${suffix}.azurewebsites.net'
}]
var backendAddressPools = {
name: '${app.appName}BackendAddresses'
properties: {
backendAddresses: backendAddresses
}
}
var backendHttpSettingsCollection = [for hostName in app.hostNames: {
name: 'backendHttpSettings_${hostName}'
properties: {
affinityCookieName: 'cookie_${hostName}'
cookieBasedAffinity: 'Enabled'
hostName: '${hostName}.${app.domain}'
pickHostNameFromBackendAddress: false
port: 443
protocol: 'Https'
requestTimeout: 30
probe: { id: resourceId('Microsoft.Network/applicationGateways/probes', appGatewayName, 'healthProbe_${hostName}') }
}
}]
var httpListeners = [for hostName in app.hostNames: {
name: 'httpListener_${hostName}'
properties: {
frontendIPConfiguration: { Id: '${appGatewayId}/frontendIPConfigurations/appGatewayFrontendIP' }
frontendPort: { Id: '${appGatewayId}/frontendPorts/frontEndPort80' }
protocol: 'Http'
hostName: '${hostName}.${app.domain}'
requireServerNameIndication: false
}
}]
var httpsListeners = [for hostName in app.hostNames: {
name: 'httpsListener_${hostName}'
properties: {
frontendIPConfiguration: { Id: '${appGatewayId}/frontendIPConfigurations/appGatewayFrontendIP' }
frontendPort: { Id: '${appGatewayId}/frontendPorts/frontEndPort443' }
protocol: 'Https'
sslCertificate: { Id: '${appGatewayId}/sslCertificates/${app.ssl.certName}' }
hostName: '${hostName}.${app.domain}'
requireServerNameIndication: true
}
}]
var httpRequestRoutingRules = [for (hostName,i) in app.hostNames: {
name: 'httpRouting_${hostName}'
properties: {
priority: (i + ruleNumberSeed + 99 )
RuleType: 'Basic'
httpListener: { id: '${appGatewayId}/httpListeners/httpListener_${hostName}' }
redirectConfiguration: { id: '${appGatewayId}/redirectConfigurations/httpsRedirect_${hostName}' }
}
}]
var httpsRequestRoutingRules = [for (hostName, i) in app.hostNames: {
name: 'httpsRouting_${hostName}'
properties: {
priority: (i + ruleNumberSeed + 500)
RuleType: 'Basic'
httpListener: { id: '${appGatewayId}/httpListeners/httpsListener_${hostName}' }
backendAddressPool: { id: '${appGatewayId}/backendAddressPools/${app.appName}BackendAddresses' }
backendHttpSettings: { id: '${appGatewayId}/backendHttpSettingsCollection/backendHttpSettings_${hostName}' }
}
}]
var probes = [for (hostName, i) in app.hostNames: {
name: 'healthProbe_${hostName}'
properties: {
protocol: 'Https'
host: '${hostName}.${app.domain}'
path: app.probe
interval: 30
timeout: 30
unhealthyThreshold: 3
pickHostNameFromBackendHttpSettings: false
minServers: 0
match: { statusCodes: [ '200' ] }
}
}]
var redirectConfigurations = [for (hostName, i) in app.hostNames: {
name: 'httpsRedirect_${hostName}'
properties: {
redirectType: 'Permanent'
targetListener: { id: resourceId('Microsoft.Network/applicationGateways/httpListeners', appGatewayName, 'httpsListener_${hostName}') }
includePath: true
includeQueryString: true
}
}]
output backendAddresses object = backendAddressPools
output backendSettings array = backendHttpSettingsCollection
output listeners array = concat(httpListeners, httpsListeners)
output probes array = probes
output redirects array = redirectConfigurations
output routingRules array = concat(httpRequestRoutingRules, httpsRequestRoutingRules)
...and here is the agPropertyAggregator.bicep
file:
param backendSettings array
param listeners array
param probes array
param redirects array
param routingRules array
// We cannot flatten() at the start of a for loop, so we must do so here.
output backendHttpSettingsCollection array = flatten(backendSettings)
output httpListeners array = flatten(listeners)
output probes array = flatten(probes)
output redirectConfigurations array = flatten(redirects)
output requestRoutingRules array = flatten(routingRules)
I'm sure there's a cleaner solution to this problem, but for now, this works.
Resource Type
Microsoft.Network/applicationGateways
Api Version
2021-08-01
Issue Type
Inaccurate property type(s)
Other Notes
Setting up an appGateway (bicep for this is in the "bicep repro" section) for scalablity with multiple apps--each of which have multiple hostnames--requires module deployment; this isn't an issue and was accomplished by setting up a bicep template to iterate over the necessary properties:
However, when deploying, I get the following warnings:
I am unable to set these as output types so they are properly parsed:
I was unable to find any other issues pertaining to this:
Bicep Repro
Confirm