azureazure-resource-managerazure-bicepazure-application-gateway

Bicep deployment - conditional within a resource


I am trying to deploy an App Gateway via Bicep template. I am using the same Bicep file for both Prod and Dev environments but the catch is that the Dev App Gateway will have some Training environment entries in it and I don't want these deployed to the Production gateway.

As such I have the following:

param environment string
var envToLower = toLower(environment)
var isDev = envToLower == 'dev'

An example of one of the things I am conditionally trying to deploy is this backendHttpSettingsCollection.

isDev ? {
    name: 'example-training-https'
    properties: {
      affinityCookieName: 'ApplicationGatewayAffinity'
      cookieBasedAffinity: 'Disabled'
      hostName: 'example.example.io'
      path: '/'
      pickHostNameFromBackendAddress: false
      port: 443
      probe: {
        id: resourceId('Microsoft.Network/applicationGateways/probes', applicationGatewayName, 'example-probe') 
      }
      protocol: 'Https'
      requestTimeout: 20
    }
 } : {}

When I try and deploy this, the ADO pipeline fails and the Deployments section for the resource group advises this error for the application-gateway:

System.ArgumentException: item.Name is null

I believe it's because I have set } : {} at the end of the ternary conditional operator and it expects a name and instead there is nothing. I just don't want this entry "example-training-https" created at all if the environment is not dev.

All the examples I could find put the if statement at the resource or module level but this is within a resource.

Has anyone else tried doing conditional deployments such as this or have some ideas of either fixing this issue or a better way of doing it while still using the same bicep file for both Dev and Prod?

I have also tried:

Using } : null instead prompts the following message in VS Code

Expected a value of type "ApplicationGatewayBackendHttpSettings" but the provided value is of type "null | object".

Using } : any(null) instead prompts this message when deploying

System.ArgumentNullException: Value cannot be null.
Parameter name: item

(Code: InvalidRequestFormat)


Solution

  • The backendHttpSettingsCollection property is an array so you would need to conditionnally add elements to the array. You can do that using the concat function:

    resource applicationGateway 'Microsoft.Network/applicationGateways@2024-05-01' = {
      ...
      properties: {
        backendHttpSettingsCollection: concat(
          [
            // common backendHttpSettingsCollection
          ],
          isDev
            ? [
                {
                  name: 'example-training-https'
                  properties: {
                    affinityCookieName: 'ApplicationGatewayAffinity'
                    cookieBasedAffinity: 'Disabled'
                    hostName: 'example.example.io'
                    path: '/'
                    pickHostNameFromBackendAddress: false
                    port: 443
                    probe: {
                      id: resourceId(
                        'Microsoft.Network/applicationGateways/probes',
                        applicationGatewayName,
                        'example-probe'
                      )
                    }
                    protocol: 'Https'
                    requestTimeout: 20
                  }
                }
              ]
            : []
        )
        ...
      }
    }