skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. Application gateway: how to define redirectConfigurations in bicep

    Here is the updated code to create application gateway with redirection rule using bicep.

    @description('Virtual Network name')
    param virtualNetworkName string = 'Application-Vnet'
    
    @description('Virtual Network address range')
    param vnetAddressPrefix string = '10.0.0.0/16'
    
    @description('Name of the subnet')
    param subnetName string = 'ApplicationGatewaySubnet'
    
    @description('Subnet address range')
    param subnetPrefix string = '10.0.0.0/24'
    
    @description('Application Gateway name')
    param applicationGatewayName string = 'applicationGatewayV2'
    
    @description('Minimum instance count for Application Gateway')
    param minCapacity int = 2
    
    @description('Maximum instance count for Application Gateway')
    param maxCapacity int = 10
    
    @description('Application Gateway Frontend port')
    param frontendPort int = 80
    
    @description('Application gateway Backend port')
    param backendPort int = 80
    
    @description('Back end pool ip addresses')
    param backendIPAddresses array = [
      {
        IpAddress: '10.0.0.4'
      }
      {
        IpAddress: '10.0.0.5'
      }
    ]
    
    @description('Cookie based affinity')
    @allowed([
      'Enabled'
      'Disabled'
    ])
    param cookieBasedAffinity string = 'Disabled'
    
    @description('Location for all resources.')
    param location string = resourceGroup().location
    
    var appGwPublicIpName = '${applicationGatewayName}-pip'
    var appGwSize = 'Standard_v2'
    
    resource virtualNetwork 'Microsoft.Network/virtualNetworks@2020-06-01' = {
      name: virtualNetworkName
      location: location
      properties: {
        addressSpace: {
          addressPrefixes: [
            vnetAddressPrefix
          ]
        }
        subnets: [
          {
            name: subnetName
            properties: {
              addressPrefix: subnetPrefix
            }
          }
        ]
      }
    }
    
    resource publicIP 'Microsoft.Network/publicIPAddresses@2020-06-01' = {
      name: appGwPublicIpName
      location: location
      sku: {
        name: 'Standard'
      }
      properties: {
        publicIPAllocationMethod: 'Static'
      }
    }
    
    resource applicationGateway 'Microsoft.Network/applicationGateways@2020-06-01' = {
      name: applicationGatewayName
      location: location
      properties: {
        sku: {
          name: appGwSize
          tier: 'Standard_v2'
        }
        autoscaleConfiguration: {
          minCapacity: minCapacity
          maxCapacity: maxCapacity
        }
        gatewayIPConfigurations: [
          {
            name: 'appGatewayIpConfig'
            properties: {
              subnet: {
                id: resourceId('Microsoft.Network/virtualNetworks/subnets', virtualNetwork.name, subnetName)
              }
            }
          }
        ]
        frontendIPConfigurations: [
          {
            name: 'appGatewayFrontendIP'
            properties: {
              publicIPAddress: {
                id: publicIP.id
              }
            }
          }
        ]
        frontendPorts: [
          {
            name: 'appGatewayFrontendPort'
            properties: {
              port: frontendPort
            }
          }
        ]
        backendAddressPools: [
          {
            name: 'appGatewayBackendPool'
            properties: {
              backendAddresses: backendIPAddresses
            }
          }
        ]
        backendHttpSettingsCollection: [
          {
            name: 'appGatewayBackendHttpSettings'
            properties: {
              port: backendPort
              protocol: 'Http'
              cookieBasedAffinity: cookieBasedAffinity
            }
          }
        ]
        httpListeners: [
          {
            name: 'appGatewayHttpListener'
            properties: {
              frontendIPConfiguration: {
                id: resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', applicationGatewayName, 'appGatewayFrontendIP')
              }
              frontendPort: {
                id: resourceId('Microsoft.Network/applicationGateways/frontendPorts', applicationGatewayName, 'appGatewayFrontendPort')
              }
              protocol: 'Http'
            }
          }
        ]
     requestRoutingRules: [
      {
        name: 'rule1'
        properties: {
          ruleType: 'Basic'
          httpListener: {
            id: resourceId('Microsoft.Network/applicationGateways/httpListeners', applicationGatewayName, 'appGatewayHttpListener')
          }
          redirectConfiguration: {
            id: resourceId('Microsoft.Network/applicationGateways/redirectConfigurations', applicationGatewayName, 'redirectConfig1')
          }
        }
      }
    ]
    
    redirectConfigurations: [
      {
        name: 'redirectConfig1'
        properties: {
          targetUrl: 'https://stackoverflow.com'
          redirectType: 'Permanent'
          includePath: true
          includeQueryString: true
        }
      }
    ]
      }
    }
    

    Output:

    enter image description here

    After running the code, the redirect rule has been created in application gateway.

    enter image description here

    Reference: Microsoft.Network applicationGateways

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search