使用 Azure Cosmos DB 的 Bicep 模板创建多个角色定义和分配
Posted
技术标签:
【中文标题】使用 Azure Cosmos DB 的 Bicep 模板创建多个角色定义和分配【英文标题】:Creating several roles definition and assignment with Bicep template for Azure Cosmos DB 【发布时间】:2021-08-19 20:39:52 【问题描述】:我尝试使用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 definition
和 assignment
时。
当我尝试将其与以下内容一起部署时:
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'))]"
]
]
]
【问题讨论】:
您是否尝试过部署为 ARM 模板以查看是否遇到相同的错误? @MarkBrown - 我相信它与 Cosmos DB 资源提供程序有关。我注意到,当我对 Cosmos DB 帐户执行任何资源管理操作(如设置标签)时,它的状态会更改为“正在更新”并保持一段时间(从几秒到几分钟)。在此期间执行的任何管理操作都会导致错误。其他资源提供者(例如存储帐户)不会发生同样的事情。 不清楚这是否是 RP 的问题。这就是为什么我要询问构建此二头肌文件的 ARM 模板是否有效。如果模板抛出相同的错误,那么可能是一个问题。如果不是,那么问题可能出在二头肌文件上。 @MarkBrown 嘿,马克,谢谢你的回答。我附上了atm模板。结果是一样的。也许你可以指点一下。 @MarkBrown 我也尝试将角色定义和角色分配移动到其他模块,但我无法传递父资源。 【参考方案1】:目前,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'))]"
]
]
]
【讨论】:
您提到“该限制将在不久的将来取消。” - 已经大约四个月了,所以只需检查一下何时将其删除。我们需要添加n
的分配数量,所以我们想使用copy
循环,但继续遇到PreConditionFailed
错误。 (我们不能链接它们,因为它们是动态的)【参考方案2】:
对于上面 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:
...
]
【讨论】:
以上是关于使用 Azure Cosmos DB 的 Bicep 模板创建多个角色定义和分配的主要内容,如果未能解决你的问题,请参考以下文章
Azure上找不到MongoDB?不妨试试Azure Cosmos DB
是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?