bicep icon indicating copy to clipboard operation
bicep copied to clipboard

condition makes the resource not included in template.json

Open santo2 opened this issue 3 years ago • 7 comments

Bicep version 0.4.1008

Describe the bug Given the following template, when param deployServerlessCosmosDb is true, then the container is not scripted into the json template. How can I reconstruct this to have it included without having to duplicate?

resource cosmosDbServer 'Microsoft.DocumentDB/databaseAccounts@2021-07-01-preview' = {
  kind: 'GlobalDocumentDB'
  name: cosmosDbServerName
  location: resourceGroup().location
  tags: tags
  properties: {
    createMode: 'Default'
    locations: [
      {
        locationName: resourceGroup().location
        failoverPriority: 0
      }
    ]
    enableAnalyticalStorage: shouldEnableAnalyticalStorage
    analyticalStorageConfiguration: cosmosDbServer_AnalyticalStorageConfiguration
    databaseAccountOfferType: 'Standard'
    consistencyPolicy: {
      defaultConsistencyLevel: 'Session'
      maxIntervalInSeconds: 5
      maxStalenessPrefix: 100
    }
    diagnosticLogSettings: {
      enableFullTextQuery: 'None'
    }
    capabilities: cosmosDbServer_capabilites
  }
}

resource PassDb 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2021-07-01-preview' = {
  parent: cosmosDbServer
  name: 'PassDb'
  properties: {
    resource: {
      id: 'PassDb'
    }
  }
}

resource QPDB 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2021-07-01-preview' = if(!deployServerlessCosmosDb) {
  parent: cosmosDbServer
  name: 'QPDB'
  properties: {
    resource: {
      id: 'QPDB'
    }
  }
}

resource container_ActorColdStorage 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2021-07-01-preview' = {
  parent: deployServerlessCosmosDb? PassDb: QPDB
  name: 'ActorColdStorage'
  properties: {
    resource: {
      id: 'ActorColdStorage'
      partitionKey: {
        paths: [
          '/Type'
        ]
        kind: 'Hash'
      }
      conflictResolutionPolicy: {
        mode: 'LastWriterWins'
        conflictResolutionPath: '/_ts'
      }
    }
  }
}

santo2 avatar Dec 17 '21 14:12 santo2

I'm not sure if I am following what the issue is. Can you include the generated JSON and where you see a problem? Is this also causing an undesirable behavior in the deployment? IOW, even if the JSON does not look the way you expect, is the final deployment result incorrect/failing?

alex-frankel avatar Dec 21 '21 23:12 alex-frankel

Hi Alex, that will be hard, the code advanced already to make it work. I did however change the script so you can run the az bicep build command on the example.

the container resource has parent: deployServerlessCosmosDb? PassDb: QPDB I expect because of this, and that there is an if(!deployServerlessCosmosDb) condition on the QPDB resource, the container resource won't get transpiled into ARM template.

Run az bicep build on template below, and the created JSON ARM template won't have the container resource.

var deployServerlessCosmosDb = true

resource cosmosDbServer 'Microsoft.DocumentDB/databaseAccounts@2021-07-01-preview' = {
  kind: 'GlobalDocumentDB'
  name: 'cosmosDbName'
  location: resourceGroup().location
  properties: {
    createMode: 'Default'
    locations: [
      {
        locationName: resourceGroup().location
        failoverPriority: 0
      }
    ]
    databaseAccountOfferType: 'Standard'
    consistencyPolicy: {
      defaultConsistencyLevel: 'Session'
      maxIntervalInSeconds: 5
      maxStalenessPrefix: 100
    }
    diagnosticLogSettings: {
      enableFullTextQuery: 'None'
    }
  }
}

resource PassDb 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2021-07-01-preview' = {
  parent: cosmosDbServer
  name: 'PassDb'
  properties: {
    resource: {
      id: 'PassDb'
    }
  }
}

resource QPDB 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2021-07-01-preview' = if(!deployServerlessCosmosDb) {
  parent: cosmosDbServer
  name: 'QPDB'
  properties: {
    resource: {
      id: 'QPDB'
    }
  }
}

resource container_ActorColdStorage 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2021-07-01-preview' = {
  parent: deployServerlessCosmosDb? PassDb: QPDB
  name: 'ActorColdStorage'
  properties: {
    resource: {
      id: 'ActorColdStorage'
      partitionKey: {
        paths: [
          '/Type'
        ]
        kind: 'Hash'
      }
      conflictResolutionPolicy: {
        mode: 'LastWriterWins'
        conflictResolutionPath: '/_ts'
      }
    }
  }
}

santo2 avatar Dec 22 '21 07:12 santo2

Got it. I am able to repro. I'm actually surprised that this compiles without errors in the first place. I didn't think conditionally setting the parent was allowed because we need to be able to generate full resource IDs at the start of the deployment..

We will take a look.

alex-frankel avatar Dec 27 '21 16:12 alex-frankel

Ok, thanks for the response. Is there a reasonable solution without having to duplicate the collection?

santo2 avatar Dec 28 '21 07:12 santo2

No, I think you will need two instances of the Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2021-07-01-preview resource and conditionally deploy those based on the value of deployServerlessCosmosDb

alex-frankel avatar Dec 30 '21 19:12 alex-frankel

I think that this is most likely something we are missing validation for. We should either:

  1. See if we can support the scenario properly with codegen. Feels unlikely as generally a resource scope must be deterministic at deploy-time, but it may be possible to support.
  2. (If not) Block it with additional validation.

anthony-c-martin avatar Jan 12 '22 20:01 anthony-c-martin

Leaving this item open to track adding actual support for expressions in the parent property.

Created #7154 to track adding validation to block the unsafe behavior.

anthony-c-martin avatar Jun 08 '22 21:06 anthony-c-martin