I have an app gateway in azure which is written in bicep. It is successfully deployed via code. I need to add a redirectConfiguration
which didn't exist in our module yet.
This is the agw code:
targetScope = 'resourceGroup'
@description('Deployment Location')
param parLocation string = resourceGroup().location
@description('The name of the AGW')
param parAppGwName string = 'alz-o-agw-01'
@description('Tags to assign to the AGW')
param parTags object = {}
param parApplicationGatewayConfiguration object = {
sku: {
name: 'WAF_v2'
tier: 'WAF_v2'
capacity: 1
}
identity: {
type: 'SystemAssigned'
}
gatewayIPConfigurations: []
frontendIPConfigurations: []
frontendPorts: []
sslCertificates: []
trustedRootCertificates: []
probes: []
backendAddressPools: []
backendHttpSettingsCollection: []
httpListeners: []
rewriteRuleSets: []
requestRoutingRules: []
urlPathMaps: []
redirectConfigurations: []
}
param parWebApplicationFirewallConfiguration object = {
enabled: false
firewallMode: 'Detection'
ruleSetType: 'OWASP'
ruleSetVersion: '3.2'
disabledRuleGroups: []
requestBodyCheck: false
exclusions: []
maxRequestBodySizeInKb: 128
fileUploadLimitInMb: 500
}
module resMappedPathRules 'getPathRules.bicep' = [
for urlMapPath in parApplicationGatewayConfiguration.urlPathMaps: {
name: urlMapPath.name
params: {
parPathRules: urlMapPath.pathRules
parGatewayName: parAppGwName
}
}
]
resource resAppGW 'Microsoft.Network/applicationGateways@2024-03-01' = {
name: parAppGwName
location: parLocation
zones: [
'1'
'2'
'3'
]
identity: parApplicationGatewayConfiguration.identity
tags: parTags
properties: {
sku: parApplicationGatewayConfiguration.sku
sslPolicy: {
policyType: 'Predefined'
policyName: 'AppGwSslPolicy20170401S'
}
enableHttp2: true
webApplicationFirewallConfiguration: {
enabled: parWebApplicationFirewallConfiguration.enabled
firewallMode: parWebApplicationFirewallConfiguration.firewallMode
ruleSetType: parWebApplicationFirewallConfiguration.ruleSetType
ruleSetVersion: parWebApplicationFirewallConfiguration.ruleSetVersion
disabledRuleGroups: parWebApplicationFirewallConfiguration.disabledRuleGroups
exclusions: parWebApplicationFirewallConfiguration.exclusions
requestBodyCheck: parWebApplicationFirewallConfiguration.requestBodyCheck
maxRequestBodySizeInKb: parWebApplicationFirewallConfiguration.maxRequestBodySizeInKb
fileUploadLimitInMb: parWebApplicationFirewallConfiguration.fileUploadLimitInMb
}
sslCertificates: [
for sslcert in parApplicationGatewayConfiguration.sslCertificates: {
name: sslcert.name
properties: {
keyVaultSecretId: 'https://${sslcert.keyvaultName}${environment().suffixes.keyvaultDns}/secrets/${sslcert.secretName}'
}
}
]
trustedRootCertificates: parApplicationGatewayConfiguration.trustedRootCertificates
gatewayIPConfigurations: parApplicationGatewayConfiguration.gatewayIPConfigurations
frontendIPConfigurations: parApplicationGatewayConfiguration.frontendIPConfigurations
frontendPorts: parApplicationGatewayConfiguration.frontendPorts
httpListeners: [
for httplistener in parApplicationGatewayConfiguration.httpListeners: {
name: httplistener.name
properties: {
protocol: 'Https'
hostName: httplistener.hostName
frontendIPConfiguration: {
id: resourceId(
'Microsoft.Network/applicationGateways/frontendIPConfigurations',
parAppGwName,
httplistener.frontendIpName
)
}
frontendPort: {
id: resourceId(
'Microsoft.Network/applicationGateways/frontendPorts',
parAppGwName,
httplistener.frontendPortName
)
}
sslCertificate: httplistener.sslCertificateName != null
? {
id: resourceId(
'Microsoft.Network/applicationGateways/sslCertificates',
parAppGwName,
httplistener.sslCertificateName
)
}
: null
firewallPolicy: httplistener.wafPolicyName != null
? {
id: resourceId(
'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies',
httplistener.wafPolicyName
)
}
: null
}
}
]
backendAddressPools: [
for (backendAddressPool, index) in parApplicationGatewayConfiguration.backendAddressPools: {
name: backendAddressPool.name
properties: {
backendAddresses: [
{
fqdn: backendAddressPool.fqdn
}
]
}
}
]
backendHttpSettingsCollection: [
for (bhsc, index) in parApplicationGatewayConfiguration.backendHttpSettingsCollection: {
name: bhsc.name
properties: {
port: bhsc.port
protocol: 'Https'
cookieBasedAffinity: 'Disabled'
pickHostNameFromBackendAddress: bhsc.pickHostNameFromBackendAddress
hostName: !bhsc.pickHostNameFromBackendAddress ? bhsc.hostName : null
requestTimeout: bhsc.?requestTimeout ?? 20
probe: {
id: resourceId('Microsoft.Network/applicationGateways/probes', parAppGwName, bhsc.probeName)
}
}
}
]
probes: [
for (probe, index) in parApplicationGatewayConfiguration.probes: {
name: probe.name
properties: {
protocol: 'Https'
pickHostNameFromBackendHttpSettings: probe.pickHostNameFromBackendHttpSettings
path: probe.path
interval: 30
timeout: 30
unhealthyThreshold: 3
minServers: 0
match: {
body: ''
statusCodes: [
'200-299'
]
}
}
}
]
rewriteRuleSets: parApplicationGatewayConfiguration.rewriteRuleSets
requestRoutingRules: [
for requestRouting in parApplicationGatewayConfiguration.requestRoutingRules: {
name: requestRouting.name
properties: {
ruleType: requestRouting.ruleType
httpListener: {
id: resourceId(
'Microsoft.Network/applicationGateways/httpListeners',
parAppGwName,
requestRouting.httpListenerName
)
}
urlPathMap: requestRouting.urlPathMapName != null
? {
id: resourceId(
'Microsoft.Network/applicationGateways/urlPathMaps',
parAppGwName,
requestRouting.urlPathMapName
)
}
: null
backendAddressPool: requestRouting.backendAddressPoolName != null
? {
id: resourceId(
'Microsoft.Network/applicationGateways/backendAddressPools',
parAppGwName,
requestRouting.backendAddressPoolName
)
}
: null
rewriteRuleSet: requestRouting.rewriteRuleSetName != null
? {
id: resourceId(
'Microsoft.Network/applicationGateways/rewriteRuleSets',
parAppGwName,
requestRouting.rewriteRuleSetName
)
}
: null
backendHttpSettings: requestRouting.backendHttpSettingsName != null
? {
id: resourceId(
'Microsoft.Network/applicationGateways/backendHttpSettingsCollection',
parAppGwName,
requestRouting.backendHttpSettingsName
)
}
: null
priority: requestRouting.priority
}
}
]
urlPathMaps: [
for (urlPathMap, index) in parApplicationGatewayConfiguration.urlPathMaps: {
name: urlPathMap.name
properties: {
defaultBackendAddressPool: {
id: resourceId(
'Microsoft.Network/applicationGateways/backendAddressPools',
parAppGwName,
urlPathMap.defaultBackendAddressPoolName
)
}
defaultBackendHttpSettings: {
id: resourceId(
'Microsoft.Network/applicationGateways/backendHttpSettingsCollection',
parAppGwName,
urlPathMap.defaultBackendHttpSettingsName
)
}
pathRules: resMappedPathRules[index].outputs.mappedPathRules
}
}
]
redirectConfigurations: [
for redirectConfig in parApplicationGatewayConfiguration.redirectConfigurations: {
name: redirectConfig.name
id: resourceId(
'Microsoft.Network/applicationGateways/redirectConfigurations',
parAppGwName,
redirectConfig.name
)
properties: {
redirectType: redirectConfig.redirectType
targetUrl: redirectConfig.targetUrl
includePath: redirectConfig.includePath
includeQueryString: redirectConfig.includeQueryString
requestRoutingRules: [
{
id: resourceId(
'Microsoft.Network/applicationGateways/requestRoutingRules',
parAppGwName,
redirectConfig.requestRoutingRuleName
)
}
]
}
}
]
}
}
output appgwResourceId string = resAppGW.id
And this is the relevant input for the redirectconfig:
redirectConfigurations: [
{
name: 'test-t-redirect-config',
redirectType: 'Permanent',
targetUrl: 'https://testurl/arm/webclient/index.html',
requestRoutingRuleName: 'test-t-https-rule',
includePath: true,
includeQueryString: true
}
]
I get the following error:
Unable to process template language expressions for resource '/subscriptions/0123456789/resourceGroups/alz-network-o-rg/providers/Microsoft.Network/applicationGateways/alz-o-agw-01' at line '1' and column '5519'. 'Unable to evaluate template language function 'resourceId': all function arguments must be string literals. Please see https://aka.ms/arm-resource-functions/#resourceid for usage details.'
I've tried to use the following ways already:
id: resourceId(
'Microsoft.Network/applicationGateways/requestRoutingRules',
'${parAppGwName}/${redirectConfig.requestRoutingRuleName}'
)
And another attempt was with concat.
It is probably something very silly that I am missing, any ideas?
Because of the fact that a redirect only needs a listener and a rule, a lot of objects where checking whether the params were being sent. They weren't because they are not necessary for a redirect. To catch this, I made the following statements on all optional components of the agw:
probe: contains(bhsc, 'probeName') && bhsc.probeName != null
? {
id: resourceId('Microsoft.Network/applicationGateways/probes',
parAppGwName, bhsc.probeName)
}
: null
the contains checks whether the value is being sent. This, combined with the null check, makes that no resourceId will be retrieved if the object which is looped over does not have the relevant keys.