练习 - 对模板规格进行更新和版本管理

已完成

整个组织现已使用你的 Azure Cosmos DB 模板规格来预配大量的 Azure Cosmos DB 新帐户。 因此,它们都已配置为使用连续备份。

安全团队最近评审了 Azure Cosmos DB 的安全功能。 他们判定新帐户应使用 Microsoft Entra身份验证和 Azure Cosmos DB 基于角色的访问控制。

在此练习中,你会将模板规格更新为包括更新后的身份验证配置的新版本。

在此过程中,你将:

  • 更新模板以重新配置备份策略。
  • 发布模板规格的新版本。
  • 验证是否模板规格是否已更新。
  • 通过部署另一个 Azure Cosmos DB 帐户来对模板规格的新版本进行测试。

更新模板

  1. 在 Visual Studio Code 中,打开 azuredeploy.json 文件。

  2. 更新 azuredeploy.json 文件以包含以下更改:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "The Azure region into which the Cosmos DB resources should be deployed."
          }
        },
        "cosmosDBAccountName": {
          "type": "string",
          "defaultValue": "[concat('toy-', uniqueString(resourceGroup().id))]",
          "maxLength": 44,
          "minLength": 3,
          "metadata": {
            "description": "The name of the Cosmos DB account. This name must be globally unique, and it must only include lowercase letters, numbers, and hyphens."
          }
        },
        "roleDefinitionFriendlyName": {
          "type": "string",
          "defaultValue": "Read and Write",
          "metadata": {
            "description": "A descriptive name for the role definition."
          }
        },
        "roleDefinitionDataActions": {
          "type": "array",
          "defaultValue": [
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*"
          ],
          "metadata": {
            "description": "The list of actions that the role definition permits."
          }
        },
        "roleAssignmentPrincipalId": {
          "type": "string",
          "metadata": {
            "description": "The object ID of the Azure AD principal that should be granted access using the role definition."
          }
        }
      },
      "variables": {
        "roleDefinitionName": "[guid('sql-role-definition', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName')))]",
        "roleAssignmentName": "[guid('sql-role-assignment', resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName')))]"
      },
      "resources": [
        {
          "type": "Microsoft.DocumentDB/databaseAccounts",
          "apiVersion": "2021-04-15",
          "name": "[parameters('cosmosDBAccountName')]",
          "kind": "GlobalDocumentDB",
          "location": "[parameters('location')]",
          "properties": {
            "consistencyPolicy": {
              "defaultConsistencyLevel": "Session"
            },
            "locations": [
              {
                "locationName": "[parameters('location')]",
                "failoverPriority": 0,
                "isZoneRedundant": false
              }
            ],
            "databaseAccountOfferType": "Standard",
            "enableAutomaticFailover": false,
            "enableMultipleWriteLocations": false,
            "backupPolicy": {
              "type": "Continuous"
            }
          }
        },
        {
          "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
          "apiVersion": "2021-04-15",
          "name": "[format('{0}/{1}', parameters('cosmosDBAccountName'), variables('roleDefinitionName'))]",
          "properties": {
            "roleName": "[parameters('roleDefinitionFriendlyName')]",
            "type": "CustomRole",
            "assignableScopes": [
              "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName'))]"
            ],
            "permissions": [
              {
                "dataActions": "[parameters('roleDefinitionDataActions')]"
              }
            ]
          },
          "dependsOn": [
            "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName'))]"
          ]
        },
        {
          "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments",
          "apiVersion": "2021-04-15",
          "name": "[format('{0}/{1}', parameters('cosmosDBAccountName'), variables('roleAssignmentName'))]",
          "properties": {
            "roleDefinitionId": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('cosmosDBAccountName'), variables('roleDefinitionName'))]",
            "principalId": "[parameters('roleAssignmentPrincipalId')]",
            "scope": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName'))]"
          },
          "dependsOn": [
            "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDBAccountName'))]",
            "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions', parameters('cosmosDBAccountName'), variables('roleDefinitionName'))]"
          ]
        }
      ]
    }
    
  3. 保存文件。

  1. 在 Visual Studio Code 中,打开 main.bicep 文件。

  2. 更新 main.bicep 文件以包含以下更改:

    @description('The Azure region into which the Cosmos DB resources should be deployed.')
    param location string = resourceGroup().location
    
    @description('The name of the Cosmos DB account. This name must be globally unique, and it must only include lowercase letters, numbers, and hyphens.')
    @minLength(3)
    @maxLength(44)
    param cosmosDBAccountName string = 'toy-${uniqueString(resourceGroup().id)}'
    
    @description('A descriptive name for the role definition.')
    param roleDefinitionFriendlyName string = 'Read and Write'
    
    @description('The list of actions that the role definition permits.')
    param roleDefinitionDataActions array = [
      'Microsoft.DocumentDB/databaseAccounts/readMetadata'
      'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*'
    ]
    
    @description('The object ID of the Azure AD principal that should be granted access using the role definition.')
    param roleAssignmentPrincipalId string
    
    var roleDefinitionName = guid('sql-role-definition', cosmosDBAccount.id)
    var roleAssignmentName = guid('sql-role-assignment', cosmosDBAccount.id)
    
    resource cosmosDBAccount 'Microsoft.DocumentDB/databaseAccounts@2021-04-15' = {
      name: cosmosDBAccountName
      kind: 'GlobalDocumentDB'
      location: location
      properties: {
        consistencyPolicy: {
          defaultConsistencyLevel: 'Session'
        }
        locations: [
          {
            locationName: location
            failoverPriority: 0
            isZoneRedundant: false
          }
        ]
        databaseAccountOfferType: 'Standard'
        enableAutomaticFailover: false
        enableMultipleWriteLocations: false
      }
    }
    
    resource roleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2021-04-15' = {
      parent: cosmosDBAccount
      name: roleDefinitionName
      properties: {
        roleName: roleDefinitionFriendlyName
        type: 'CustomRole'
        assignableScopes: [
          cosmosDBAccount.id
        ]
        permissions: [
          {
            dataActions: roleDefinitionDataActions
          }
        ]
      }
    }
    
    resource roleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2021-04-15' = {
      parent: cosmosDBAccount
      name: roleAssignmentName
      properties: {
        roleDefinitionId: roleDefinition.id
        principalId: roleAssignmentPrincipalId
        scope: cosmosDBAccount.id
      }
    }
    
  3. 保存文件。

发布模板规格的新版本

在 Visual Studio Code 终端中使用此 Azure PowerShell cmdlet 发布模板规格:

New-AzTemplateSpec `
  -ResourceGroupName <rgn>[sandbox resource group name]</rgn> `
  -Name ToyCosmosDBAccount `
  -Version '2.0' `
  -VersionDescription 'Adds Cosmos DB role-based access control.' `
  -TemplateFile main.bicep
New-AzTemplateSpec `
  -ResourceGroupName <rgn>[sandbox resource group name]</rgn> `
  -Name ToyCosmosDBAccount `
  -Version '2.0' `
  -VersionDescription 'Adds Cosmos DB role-based access control.' `
  -TemplateFile azuredeploy.json

在 Visual Studio Code 终端中使用此 Azure CLI 命令发布模板规格:

az ts create \
  --name ToyCosmosDBAccount \
  --version 2.0 \
  --version-description "Adds Cosmos DB role-based access control." \
  --template-file main.bicep
az ts create \
  --name ToyCosmosDBAccount \
  --version 2.0 \
  --version-description "Adds Cosmos DB role-based access control." \
  --template-file azuredeploy.json

验证模板规格

  1. 在浏览器中返回到 Azure 门户。 转到你的资源组。

  2. 选择模板规格。请注意,现在列出的最新版本是 2.0 版。

    Screenshot of the Azure portal interface for the template spec, showing the latest version as 2.0.

  3. 选择“版本”菜单项。 请注意,现在两个版本都已列出。

    Screenshot of the Azure portal interface for the template spec, showing the list of versions as 1.0 and 2.0.

    使用模板规格版本,可以在需要的时候返回模板规格的旧版本。

部署新的模板规格版本

  1. 通过运行以下 Azure PowerShell 命令获取新模板规格版本的资源 ID:

    $templateSpecVersionResourceId = ( `
       Get-AzTemplateSpec `
          -ResourceGroupName <rgn>[sandbox resource group name]</rgn> `
          -Name ToyCosmosDBAccount `
          -Version 2.0 `
       ).Versions[0].Id
    

    请注意,可以使用 Versions 属性来获取模板规格版本的资源 ID。

  2. 新模板规格版本具有一个代表用户主体 ID 的参数。 使用以下命令,获取自己的用户帐户的主体 ID:

    $token = (Get-AzAccessToken -ResourceUrl "https://graph.windows.net/").Token
    $userObjectId = (Invoke-RestMethod -Uri 'https://graph.windows.net/me?api-version=1.6' -Headers @{ 'Authorization' = "Bearer $token"}).objectID
    

    该命令使用 Microsoft Graph API 来查询你自己的用户配置文件。

  3. 在 Visual Studio Code 终端中使用此 Azure PowerShell 命令部署模板规格:

    New-AzResourceGroupDeployment `
      -TemplateSpecId $templateSpecVersionResourceId `
      -roleAssignmentPrincipalId $userObjectId
    
  1. 通过运行以下 Azure CLI 命令获取模板规格版本的资源 ID:

    id=$(az ts show \
     --name ToyCosmosDBAccount \
     --resource-group "<rgn>[sandbox resource group name]</rgn>" \
     --version "2.0" \
     --query "id")
    
  2. 在 Visual Studio Code 终端中使用此 Azure CLI 命令部署模板规格:

    az deployment group create \
     --template-spec $id \
     --parameters roleAssignmentPrincipalId="d68d19b3-d7ef-4ae9-9ee4-90695a4e417d"
    

该部署过程可能需要一两分钟才能完成。

验证部署

  1. 在浏览器中返回到 Azure 门户。 转到你的资源组。

  2. 选择“部署”旁的“2 个已成功”。

    Screenshot of the Azure portal interface for the resource group overview, with the deployments section showing that two succeeded.

  3. 选择最近的部署。

    Screenshot of the Azure portal interface for the deployments, with two deployments listed.

  4. 选择“部署详细信息”将其展开。 确认已部署 Azure Cosmos DB 基于角色的访问控制的资源。

    Screenshot of the Azure portal interface for the specific deployment, with the Azure Cosmos DB resources listed.