Search code examples
azureazure-pipelinesazure-resource-managerazure-bicep

Conditional Parent in Bicep


I have a Bicep script deployed as part of an Azure Pipeline. Through some googling, I've managed to almost implement a "create if not exists" for resources using a Powershell Script further up the pipeline as described at https://ochzhen.com/blog/check-if-resource-exists-azure-bicep

The issue seems to be I can't pass an ID or a conditional reference as a parent. What I;m trying to do is:

param isFdEndpointExisting bool
...
resource endpoint 'Microsoft.Cdn/profiles/afdEndpoints@2020-09-01' =if(!isFdEndpointExisting) {
  name: fdEndpointName
  parent: fdProfile
  ... //  params to initialize here
}

resource endpointExisting 'Microsoft.Cdn/profiles/afdEndpoints@2020-09-01'existing =if(isFdEndpointExisting) {
  name: fdEndpointName
  parent: fdProfile
}

resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2020-09-01' =if(!isFdRouteExisting) {
  name: routeName
  parent: isFdEndpointExisting ? endpointExisting : endpoint

The error I get is: The "parent" property only permits direct references to resources. Expressions are not supported.bicep(BCP240)

Is there an alternative way of doing this. It feels a little clunky.


Solution

  • You could create the endpoint inside a module:

    // fd-route.bicep
    
    param frontDoorName string
    param endpointName string
    param routeName string
    
    ... 
    resource frontDoor 'Microsoft.Cdn/profiles@2022-11-01-preview'existing = {
      name: frontDoorName
    }
    
    resource endpoint 'Microsoft.Cdn/profiles/afdEndpoints@2022-11-01-preview'existing = {
      parent: frontDoor
      name: endpointName  
    }
    
    resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2020-09-01' = {
      parent: endpoint
      name: routeName
      ...
    }
    

    Then you can invoke it like that from your main

    param isFdEndpointExisting bool
    param fdProfileName string
    param fdEndpointName string
    param routeName string 
    
    ...
    
    // Get a ference to front door
    resource fdProfile 'Microsoft.Cdn/profiles@2020-09-01' existing = {
      name: fdProfileName
    }
    
    // Create the endpoit if not exists
    resource endpoint 'Microsoft.Cdn/profiles/afdEndpoints@2020-09-01' =if(!isFdEndpointExisting) {
      parent: fdProfile
      name: fdEndpointName  
      ...  
    }
    
    // Get a reference to the existing endpoint if already exists
    resource endpointExisting 'Microsoft.Cdn/profiles/afdEndpoints@2020-09-01'existing =if(isFdEndpointExisting) {
      name: fdEndpointName
      parent: fdProfile
    }
    
    // Create the rouyte
    module route 'fd-route.bicep' = {
      name: routeName
      params: {
        frontDoorName: fdProfile.name
        endpointName: isFdEndpointExisting ? endpointExisting.name : endpoint.name
        routeName: routeName
        ...
      }
    }