使用 Azure Cosmos DB 的 Bicep 模板创建多个角色定义和分配

Creating several roles definition and assignment with Bicep template for Azure Cosmos DB

我尝试使用 Bicep 模板为一个 Azure CosmosDB SQL API 帐户创建两个 role definitions 和两个 role assignments

我用 az bicep decompile 反编译了下面的 arm 模板: https://github.com/Azure/azure-quickstart-templates/blob/master/101-cosmosdb-sql-rbac/azuredeploy.json

我得到了以下结果:

resource accountName_readOnlyRoleDefinitionId 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2020-06-01-preview' = {
  parent: accountName_resource
  name: '${readOnlyRoleDefinitionId}'
  properties: {
    roleName: readOnlyRoleDefinitionName
    type: 'CustomRole'
    assignableScopes: [
      accountName_resource.id
    ]
    permissions: [
      {
        dataActions: readOnlyRoleDataActions
      }
    ]
  }
}

resource accountName_readOnlyRoleAssignmentId 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2020-06-01-preview' = {
  parent: accountName_resource
  name: '${readOnlyRoleAssignmentId}'
  properties: {
    roleDefinitionId: accountName_readOnlyRoleDefinitionId.id
    principalId: readOnlyPrincipalId
    scope: accountName_resource.id
  }
}

有效,但只有当我有一个 role definitionassignment.

当我尝试将其与以下内容一起部署时:

resource accountName_readWriteRoleDefinitionId 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2020-06-01-preview' = {
  parent: accountName_resource
  name: '${readWriteRoleDefinitionId}'
  properties: {
    roleName: readWriteRoleDefinitionName
    type: 'CustomRole'
    assignableScopes: [
      accountName_resource.id
    ]
    permissions: [
      {
        dataActions: readWriteRoleDataActions
      }
    ]
  }
}

resource accountName_readWriteRoleAssignmentId 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2020-06-01-preview' = {
  parent: accountName_resource
  name: '${readWriteRoleAssignmentId}'
  properties: {
    roleDefinitionId: accountName_readWriteRoleDefinitionId.id
    principalId: readWritePrincipalId
    scope: accountName_resource.id
  }
}

我遇到以下错误:

Deployment failed. Correlation ID: 8fe92bd6-6db6-4d9a-98b5-5f78811cc741. {
  "status": "Failed",
  "error": {
    "code": "ResourceDeploymentFailure",
    "message": "The resource operation completed with terminal provisioning state 'Failed'.",
    "details": [
      {
        "code": "DeploymentFailed",
        "message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.",
        "details": [
          {
            "code": "PreconditionFailed",
            "message": "{\r\n  \"code\": \"PreconditionFailed\",\r\n  \"message\": \"There is another user operation in progress which requires an exclusive lock on [cosmossqlapibiceptest]. Please retry after sometime.\r\nActivityId: 7d56ef38-85ee-490e-9819-cc74afc142d3, Microsoft.Azure.Documents.Common/2.14.0\"\r\n}"
          }
        ]
      }
    ]
  }
}

我也尝试过迭代而不是分离资源,为每个角色使用嵌套模块,但这没有帮助。

更新 2021-06-02

我也试过部署 json 文件,但结果一样。我附上 arm template:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.3.539.46024",
      "templateHash": "54838909324108202"
    }
  },
  "functions": [],
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "name": "cosmos_deployment",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "accountName": {
            "value": "add_yours_input"
          },
          "databaseName": {
            "value": "add_yours_input"
          },
          "containerName": {
            "value": "add_yours_input"
          },
          "timeToLive": {
            "value": 2592000
          },
          "readOnlyPrincipalId": {
            "value": "add_yours_input"
          },
          "readWritePrincipalId": {
            "value": "add_yours_input"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "metadata": {
            "_generator": {
              "name": "bicep",
              "version": "0.3.539.46024",
              "templateHash": "10083279953983831862"
            }
          },
          "parameters": {
            "location": {
              "type": "string",
              "defaultValue": "[resourceGroup().location]"
            },
            "accountName": {
              "type": "string"
            },
            "databaseName": {
              "type": "string"
            },
            "containerName": {
              "type": "string"
            },
            "timeToLive": {
              "type": "int"
            },
            "throughput": {
              "type": "int",
              "defaultValue": 400,
              "metadata": {
                "description": "The throughput for the container"
              },
              "maxValue": 1000000,
              "minValue": 400
            },
            "publicNetworkAccess": {
              "type": "string",
              "defaultValue": "Enabled",
              "allowedValues": [
                "Enabled",
                "Disabled"
              ]
            },
            "readOnlyPrincipalId": {
              "type": "string",
              "metadata": {
                "description": "Object ID of the AAD identity. Must be a GUID."
              }
            },
            "readOnlyRoleDefinitionName": {
              "type": "string",
              "defaultValue": "Read Only Role"
            },
            "readOnlyRoleDataActions": {
              "type": "array",
              "defaultValue": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
              ],
              "metadata": {
                "description": "Data actions permitted by the ReadOnlyRole Role Definition"
              }
            },
            "readWritePrincipalId": {
              "type": "string",
              "metadata": {
                "description": "Object ID of the AAD identity. Must be a GUID."
              }
            },
            "readWriteRoleDefinitionName": {
              "type": "string",
              "defaultValue": "Read Write Role"
            },
            "readWriteRoleDataActions": {
              "type": "array",
              "defaultValue": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
              ],
              "metadata": {
                "description": "Data actions permitted by the ReadWriteOnlyRole Role Definition"
              }
            }
          },
          "functions": [],
          "variables": {
            "readOnlyRoleDefinitionId": "[guid('sql-read-role-definition-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readOnlyRoleAssignmentId": "[guid('sql-read-role-assignment-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readWriteRoleDefinitionId": "[guid('sql-write-role-definition-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readWriteRoleAssignmentId": "[guid('sql-write-role-assignment-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]"
          },
          "resources": [
            {
              "type": "Microsoft.DocumentDB/databaseAccounts",
              "apiVersion": "2021-03-01-preview",
              "name": "[parameters('accountName')]",
              "location": "[parameters('location')]",
              "kind": "GlobalDocumentDB",
              "properties": {
                "createMode": "Default",
                "consistencyPolicy": {
                  "defaultConsistencyLevel": "Strong"
                },
                "locations": [
                  {
                    "locationName": "[parameters('location')]",
                    "failoverPriority": 0,
                    "isZoneRedundant": false
                  }
                ],
                "databaseAccountOfferType": "Standard",
                "enableAutomaticFailover": false,
                "enableMultipleWriteLocations": false,
                "publicNetworkAccess": "[parameters('publicNetworkAccess')]"
              }
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases",
              "apiVersion": "2021-03-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), parameters('databaseName'))]",
              "properties": {
                "resource": {
                  "id": "[parameters('databaseName')]"
                }
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers",
              "apiVersion": "2021-03-01-preview",
              "name": "[format('{0}/{1}/{2}', parameters('accountName'), parameters('databaseName'), parameters('containerName'))]",
              "location": "[parameters('location')]",
              "tags": {},
              "properties": {
                "resource": {
                  "id": "[parameters('containerName')]",
                  "partitionKey": {
                    "paths": [
                      "/partitionKey"
                    ],
                    "kind": "Hash"
                  },
                  "indexingPolicy": {
                    "indexingMode": "consistent",
                    "includedPaths": [
                      {
                        "path": "/a/b/?",
                        "indexes": [
                          {
                            "kind": "Hash",
                            "dataType": "String",
                            "precision": -1
                          }
                        ]
                      }
                    ],
                    "excludedPaths": [
                      {
                        "path": "/*"
                      }
                    ]
                  },
                  "defaultTtl": 1
                },
                "options": {
                  "throughput": "[parameters('throughput')]"
                }
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('accountName'), parameters('databaseName'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
              "properties": {
                "roleName": "[parameters('readOnlyRoleDefinitionName')]",
                "type": "CustomRole",
                "assignableScopes": [
                  "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
                ],
                "permissions": [
                  {
                    "dataActions": "[parameters('readOnlyRoleDataActions')]"
                  }
                ]
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readOnlyRoleAssignmentId'))]",
              "properties": {
                "roleDefinitionId": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
                "principalId": "[parameters('readOnlyPrincipalId')]",
                "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
              "properties": {
                "roleName": "[parameters('readWriteRoleDefinitionName')]",
                "type": "CustomRole",
                "assignableScopes": [
                  "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
                ],
                "permissions": [
                  {
                    "dataActions": "[parameters('readWriteRoleDataActions')]"
                  }
                ]
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readWriteRoleAssignmentId'))]",
              "properties": {
                "roleDefinitionId": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
                "principalId": "[parameters('readWritePrincipalId')]",
                "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            }
          ]
        }
      }
    }
  ]
}

目前,Cosmos 资源提供程序一次只允许您创建其中一个。该限制将在不久的将来取消。

作为解决方法,将第二个角色定义链接到之前的角色分配,以便按顺序创建它们。这个更新的 ARM 模板应该可以解决问题。

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.3.539.46024",
      "templateHash": "54838909324108202"
    }
  },
  "functions": [],
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "name": "cosmos_deployment",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "accountName": {
            "value": "add_yours_input"
          },
          "databaseName": {
            "value": "add_yours_input"
          },
          "containerName": {
            "value": "add_yours_input"
          },
          "timeToLive": {
            "value": 2592000
          },
          "readOnlyPrincipalId": {
            "value": "add_yours_input"
          },
          "readWritePrincipalId": {
            "value": "add_yours_input"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "metadata": {
            "_generator": {
              "name": "bicep",
              "version": "0.3.539.46024",
              "templateHash": "10083279953983831862"
            }
          },
          "parameters": {
            "location": {
              "type": "string",
              "defaultValue": "[resourceGroup().location]"
            },
            "accountName": {
              "type": "string"
            },
            "databaseName": {
              "type": "string"
            },
            "containerName": {
              "type": "string"
            },
            "timeToLive": {
              "type": "int"
            },
            "throughput": {
              "type": "int",
              "defaultValue": 400,
              "metadata": {
                "description": "The throughput for the container"
              },
              "maxValue": 1000000,
              "minValue": 400
            },
            "publicNetworkAccess": {
              "type": "string",
              "defaultValue": "Enabled",
              "allowedValues": [
                "Enabled",
                "Disabled"
              ]
            },
            "readOnlyPrincipalId": {
              "type": "string",
              "metadata": {
                "description": "Object ID of the AAD identity. Must be a GUID."
              }
            },
            "readOnlyRoleDefinitionName": {
              "type": "string",
              "defaultValue": "Read Only Role"
            },
            "readOnlyRoleDataActions": {
              "type": "array",
              "defaultValue": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
              ],
              "metadata": {
                "description": "Data actions permitted by the ReadOnlyRole Role Definition"
              }
            },
            "readWritePrincipalId": {
              "type": "string",
              "metadata": {
                "description": "Object ID of the AAD identity. Must be a GUID."
              }
            },
            "readWriteRoleDefinitionName": {
              "type": "string",
              "defaultValue": "Read Write Role"
            },
            "readWriteRoleDataActions": {
              "type": "array",
              "defaultValue": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
                "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
              ],
              "metadata": {
                "description": "Data actions permitted by the ReadWriteOnlyRole Role Definition"
              }
            }
          },
          "functions": [],
          "variables": {
            "readOnlyRoleDefinitionId": "[guid('sql-read-role-definition-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readOnlyRoleAssignmentId": "[guid('sql-read-role-assignment-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readWriteRoleDefinitionId": "[guid('sql-write-role-definition-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]",
            "readWriteRoleAssignmentId": "[guid('sql-write-role-assignment-', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')))]"
          },
          "resources": [
            {
              "type": "Microsoft.DocumentDB/databaseAccounts",
              "apiVersion": "2021-03-01-preview",
              "name": "[parameters('accountName')]",
              "location": "[parameters('location')]",
              "kind": "GlobalDocumentDB",
              "properties": {
                "createMode": "Default",
                "consistencyPolicy": {
                  "defaultConsistencyLevel": "Strong"
                },
                "locations": [
                  {
                    "locationName": "[parameters('location')]",
                    "failoverPriority": 0,
                    "isZoneRedundant": false
                  }
                ],
                "databaseAccountOfferType": "Standard",
                "enableAutomaticFailover": false,
                "enableMultipleWriteLocations": false,
                "publicNetworkAccess": "[parameters('publicNetworkAccess')]"
              }
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases",
              "apiVersion": "2021-03-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), parameters('databaseName'))]",
              "properties": {
                "resource": {
                  "id": "[parameters('databaseName')]"
                }
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers",
              "apiVersion": "2021-03-01-preview",
              "name": "[format('{0}/{1}/{2}', parameters('accountName'), parameters('databaseName'), parameters('containerName'))]",
              "location": "[parameters('location')]",
              "tags": {},
              "properties": {
                "resource": {
                  "id": "[parameters('containerName')]",
                  "partitionKey": {
                    "paths": [
                      "/partitionKey"
                    ],
                    "kind": "Hash"
                  },
                  "indexingPolicy": {
                    "indexingMode": "consistent",
                    "includedPaths": [
                      {
                        "path": "/a/b/?",
                        "indexes": [
                          {
                            "kind": "Hash",
                            "dataType": "String",
                            "precision": -1
                          }
                        ]
                      }
                    ],
                    "excludedPaths": [
                      {
                        "path": "/*"
                      }
                    ]
                  },
                  "defaultTtl": 1
                },
                "options": {
                  "throughput": "[parameters('throughput')]"
                }
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('accountName'), parameters('databaseName'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
              "properties": {
                "roleName": "[parameters('readOnlyRoleDefinitionName')]",
                "type": "CustomRole",
                "assignableScopes": [
                  "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
                ],
                "permissions": [
                  {
                    "dataActions": "[parameters('readOnlyRoleDataActions')]"
                  }
                ]
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readOnlyRoleAssignmentId'))]",
              "properties": {
                "roleDefinitionId": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
                "principalId": "[parameters('readOnlyPrincipalId')]",
                "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readOnlyRoleDefinitionId'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
              "properties": {
                "roleName": "[parameters('readWriteRoleDefinitionName')]",
                "type": "CustomRole",
                "assignableScopes": [
                  "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
                ],
                "permissions": [
                  {
                    "dataActions": "[parameters('readWriteRoleDataActions')]"
                  }
                ]
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments', variables('readOnlyRoleDefinitionId'))]"
              ]
            },
            {
              "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
              "apiVersion": "2020-06-01-preview",
              "name": "[format('{0}/{1}', parameters('accountName'), variables('readWriteRoleAssignmentId'))]",
              "properties": {
                "roleDefinitionId": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
                "principalId": "[parameters('readWritePrincipalId')]",
                "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              },
              "dependsOn": [
                "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('accountName'), variables('readWriteRoleDefinitionId'))]",
                "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName'))]"
              ]
            }
          ]
        }
      }
    }
  ]
}

对于上面 Brian 的问题 - 我能够通过在循环之前添加 @batchSize(1) 装饰器(对于角色分配及其父资源)来解决与 copy 使用相关的上述问题。

这样一一部署资源:

@batchSize(1)
module azureFunction '../modules/app-service/bicep' = [for function in functions: {
  ...
}]

@batchSize(1)
module sqlRoleAssignment '../modules/sql-role-assignment.bicep' = [for function in functions: {
  ...
}]

尝试在每个作业之间使用 dependsOn:[] - https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/resource-dependencies#explicit-dependency