Search code examples
azureazure-cosmosdbazure-bicepazure-cosmosdb-mongoapi

Error creating CosmosDB Mongo Collections via bicep


I have a bicep template that attempts to create a CosmosDb Mongo database account, and add 4 databases to this account, each with their own respective collections.

Database A and B have 1 collection each. Database C and D have about 15 collections each.

During deployment, roughly 2 out of 30 collections will fail to initialize. The Azure portal reports this error on the Deployment blade for the module in question:

ActivityId: f88f0f96-52b5-4d18-a10a-6343cc71bcd2, Microsoft.Azure.Documents.Common/2.14.0 (Code: InternalServerError)

If I remove the DependsOn attributes, the Azure portal will report errors with a 429 Status Code (Too Many Attempts) for 80% of the attempted collections.

here's my cosmos.bicep template:

param location string = resourceGroup().location
param tags object = {}

param masterCollection array = [
    {
      name: 'apikeyrecords'
      id: 'apikeyrecords'
      shardKey: 'Hash'
      indexKey: '_id'
  }
]

param daprCollection array = [
    {
      name: 'daprCollection'
      id: 'daprCollection'
      shardKey: 'Hash'
      indexKey: '_id'
  }
]

param defaultCollections array = [
  ...
  {
    name: 'locations'
    id: 'locations'
    shardKey: 'Hash'
    indexKey: '_id'
  }
  {
    name: 'templates'
    id: 'templates'
    shardKey: 'Hash'
    indexKey: '_id'
  }
  ...
]

param keyVaultName string
param connectionStringKey string = 'AZURE-COSMOS-CONNECTION-STRING'

module cosmosAccount '../core/database/cosmos/mongo/cosmos-mongo-account.bicep' = {
  name: 'cosmos-mongo-account'
  params: {
    name: accountName
    location: location
    keyVaultName: keyVaultName
    tags: tags
    connectionStringKey: connectionStringKey
  }
}

resource databaseA 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases@2023-11-15' = {
  name: '${accountName}/database-a'
  tags: tags
  properties: {
    resource: { id: 'database-a' }
  }

  dependsOn: [
    cosmosAccount
  ]
}

resource alist 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections@2023-11-15' = [for collection in masterCollection: {
  parent: databaseA
  name: '${collection.name}'
  properties: {
    resource: {
    id: collection.id
    shardKey: { _id: collection.shardKey }
    indexes: [ 
      { key: { keys: [ collection.indexKey ] } } 
      { key: { keys: [ '$**' ] } }
    ]
    }
  }
}]


resource databaseb 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases@2023-11-15' = {
  name: '${accountName}/database-b'
  tags: tags
  properties: {
    resource: { id: 'database-b' }
  }

  dependsOn: [
    cosmosAccount
    databaseA
    alist
  ]
}

resource blist 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections@2023-11-15' = [for collection in daprCollection: {
  parent: databaseB
  name: '${collection.name}'
  properties: {
    resource: {
    id: collection.id
    shardKey: { _id: collection.shardKey }
    indexes: [ 
      { key: { keys: [ collection.indexKey ] } } 
      { key: { keys: [ '$**' ] } }
    ]
    }
  }
}]


resource databaseC 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases@2023-11-15' = {
  name: '${accountName}/database-c'
  tags: tags
  properties: {
    resource: { id: 'database-c' }
  }

  dependsOn: [
    cosmosAccount
    databaseA
    databaseB
    blist
  ]
}

resource clist 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections@2023-11-15' = [for collection in defaultCollections: {
  parent: databaseC
  name: '${collection.name}'
  properties: {
    resource: {
    id: collection.id
    shardKey: { _id: collection.shardKey }
    indexes: [ 
      { key: { keys: [ collection.indexKey ] } } 
      { key: { keys: [ '$**' ] } }
    ]
    }
  }
}]


resource databaseD 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases@2023-11-15' = {
  name: '${accountName}/database-d'
  tags: tags
  properties: {
    resource: { id: 'database-d' }
  }

  dependsOn: [
    cosmosAccount
    databaseA
    databaseB
    databaseC
    clist
  ]
}

resource dlist 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections@2023-11-15' = [for collection in defaultCollections: {
  parent: databaseD
  name: '${collection.name}'
  properties: {
    resource: {
    id: collection.id
    shardKey: { _id: collection.shardKey }
    indexes: [ 
      { key: { keys: [ collection.indexKey ] } } 
      { key: { keys: [ '$**' ] } }
    ]
    }
  }
}]

output accountName string = accountName

Is there a more appropriate way to instantiate mongo database collections during infrastructure deployment?


Solution

  • As was so kindly pointed out in the comments, my solution was to utilize the @batchSize() decorator on any mongo collection for-loops:

    @batchSize(3)
    resource clist 'Microsoft.DocumentDB/databaseAccounts/mongodbDatabases/collections@2023-11-15' = [for collection in defaultCollections: {
      parent: databaseC
      name: '${collection.name}'
      properties: {
        resource: {
        id: collection.id
        shardKey: { _id: collection.shardKey }
        indexes: [ 
          { key: { keys: [ collection.indexKey ] } } 
          { key: { keys: [ '$**' ] } }
        ]
        }
      }
    }]