如何使用托管标识从 Azure 虚拟机连接到 Azure Cosmos DB

在本文中,我们会将虚拟机设置为使用托管标识连接到 Azure Cosmos DB。 Azure Cosmos DB 是一种用于新式应用开发的完全托管的 NoSQL 数据库。 Azure 资源的托管标识使应用程序可以在访问服务时进行身份验证,这些服务支持通过 Azure 所管理的标识进行的 Microsoft Entra 身份验证。

先决条件

创建资源组

创建名为“mi-test”的资源组。 我们会将此资源组用于本教程中使用的所有资源。

创建具有托管标识的 Azure VM

对于本教程,需要一个 Azure 虚拟机。 创建启用了系统分配的托管标识的虚拟机,并将其命名为“mi-vm-01”。 还可以在我们之前创建的资源组 (mi-test) 中,创建名为“mi-ua-01”的用户分配的托管标识 。 如果使用用户分配的托管标识,则可以在创建期间将其分配到 VM。

创建具有系统分配的托管标识的虚拟机

若要创建启用了系统分配的托管标识的 Azure VM,你的帐户需要虚拟机参与者角色分配。 不需要其他 Microsoft Entra 角色分配。

  • 在“Azure 门户”中,搜索“虚拟机” 。
  • 选择“创建”
  • 在“基本信息”选项卡中,提供必填的信息。
  • 选择“下一步: 磁盘 >”
  • 继续根据需要填写信息,在“管理”选项卡中,找到“标识”部分,然后选中“系统分配的托管标识”旁边的框

Image showing how to enable system assigned managed identities while creating a VM.

有关详细信息,请参阅 Azure 虚拟机文档:

创建具有用户分配的托管标识的 VM

以下步骤演示如何创建配置了用户分配的托管标识的虚拟机。

当前,Azure 门户不支持在创建 VM 期间分配用户分配的托管标识。 应创建一个虚拟机,并向其分配一个用户分配的托管标识。

使用 Azure 门户在 VM 上配置 Azure 资源托管标识

创建 Azure Cosmos DB 帐户

拥有一个具有用户分配的托管标识或系统分配的托管标识的 VM 后,我们需要一个你对其有管理权限的可用 Azure Cosmos DB 帐户。 如果需要为本教程创建 Azure Cosmos DB 帐户,请参阅 Azure Cosmos DB 快速入门,了解此操作的详细步骤。

注意

托管标识可用于访问支持 Microsoft Entra 身份验证的任何 Azure 资源。 本教程假设 Azure Cosmos DB 帐户将按如下所示进行配置。

设置 说明
订阅 订阅名称 选择要用于此 Azure Cosmos DB 帐户的 Azure 订阅。
资源组 资源组名称 选择“mi-test”,或者选择“新建”,然后输入新资源组的唯一名称 。
帐户名 唯一的名称 输入标识 Azure Cosmos 帐户的名称。 由于 documents.azure.cn 将追加到所提供的名称以创建 URI,因此,请使用唯一的名称。

名称只能包含小写字母、数字和连字符 (-)。 它的长度必须介于 3-44 个字符之间。
API 要创建的帐户的类型 选择“Azure Cosmos DB for NoSQL”,以便使用 SQL 语法创建文档数据库并进行查询。

详细了解 SQL API
位置 离用户最近的区域 选择用于托管 Azure Cosmos DB 帐户的地理位置。 使用离用户最近的位置,使他们能够以最快的速度访问数据。

注意

如果正在进行测试,你可能想要应用 Azure Cosmos DB 免费层折扣。 使用 Azure Cosmos DB 免费层,你将在帐户中免费获得 1000 RU/秒的吞吐量和 25 GB 的存储。 了解免费层的详细信息。 请记住,就本教程来说,此选择没有任何区别。

授予访问权限

此时,我们应该拥有一个配置了托管标识的虚拟机和一个 Azure Cosmos DB 帐户。 需要向托管标识授予几个不同的角色,才能继续。

  • 首先使用 Azure RBAC 授予对 Azure Cosmos DB 管理平面的访问权限。 托管标识需要分配有 DocumentDB 帐户参与者角色,才能创建数据库和容器。

  • 还需要使用 Azure Cosmos DB RBAC 向托管标识授予参与者角色。 可以参考以下具体步骤。

注意

我们将使用“Cosmos DB 内置数据参与者”角色。 若要授予访问权限,需要将角色定义与标识关联。 在此例中,托管标识是与虚拟机关联的。

目前,Azure 门户中未提供任何角色分配选项

访问数据

使用 Azure.identity 库在应用程序中启用身份验证,就可以使用托管标识访问 Azure Cosmos DB。 可以直接调用 ManagedIdentityCredential 或使用 DefaultAzureCredential

ManagedIdentityCredential 类尝试使用分配给部署环境的托管标识进行身份验证。 DefaultAzureCredential 类将按顺序执行不同的身份验证选项。 DefaultAzureCredential 尝试的第二个身份验证选项是托管标识。

在以下示例中,你将创建数据库、容器、容器中的项,并使用虚拟机的系统分配的托管标识重新读取新创建的项。 如果要使用用户分配的托管标识,则需要通过指定托管标识的客户端 ID 来指定用户分配的托管标识。

string userAssignedClientId = "<your managed identity client Id>";
var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });

若要使用以下示例,需要具有以下 NuGet 包:

  • Azure.Identity
  • Microsoft.Azure.Cosmos
  • Microsoft.Azure.Management.CosmosDB

除了上述 NuGet 包,还需要启用“包括预发行版”,然后添加 Azure.ResourceManager.CosmosDB。

using Azure.Identity;
using Azure.ResourceManager.CosmosDB;
using Azure.ResourceManager.CosmosDB.Models;
using Microsoft.Azure.Cosmos;
using System;
using System.Threading.Tasks;

namespace MITest
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Replace the placeholders with your own values
            var subscriptionId = "Your subscription ID";
            var resourceGroupName = "You resource group";
            var accountName = "Cosmos DB Account name";
            var databaseName = "mi-test";
            var containerName = "container01";

            // Authenticate to Azure using Managed Identity (system-assigned or user-assigned)
            var tokenCredential = new DefaultAzureCredential();

            // Create the Cosmos DB management client using the subscription ID and token credential
            var managementClient = new CosmosDBManagementClient(tokenCredential)
            {
                SubscriptionId = subscriptionId
            };

            // Create the Cosmos DB data client using the account URL and token credential
            var dataClient = new CosmosClient($"https://{accountName}.documents.azure.cn:443/", tokenCredential);

            // Create a new database using the management client
            var createDatabaseOperation = await managementClient.SqlResources.StartCreateUpdateSqlDatabaseAsync(
                resourceGroupName,
                accountName,
                databaseName,
                new SqlDatabaseCreateUpdateParameters(new SqlDatabaseResource(databaseName), new CreateUpdateOptions()));
            await createDatabaseOperation.WaitForCompletionAsync();

            // Create a new container using the management client
            var createContainerOperation = await managementClient.SqlResources.StartCreateUpdateSqlContainerAsync(
                resourceGroupName,
                accountName,
                databaseName,
                containerName,
                new SqlContainerCreateUpdateParameters(new SqlContainerResource(containerName), new CreateUpdateOptions()));
            await createContainerOperation.WaitForCompletionAsync();

            // Create a new item in the container using the data client
            var partitionKey = "pkey";
            var id = Guid.NewGuid().ToString();
            await dataClient.GetContainer(databaseName, containerName)
                .CreateItemAsync(new { id = id, _partitionKey = partitionKey }, new PartitionKey(partitionKey));

            // Read back the item from the container using the data client
            var pointReadResult = await dataClient.GetContainer(databaseName, containerName)
                .ReadItemAsync<dynamic>(id, new PartitionKey(partitionKey));

            // Run a query to get all items from the container using the data client
            await dataClient.GetContainer(databaseName, containerName)
                .GetItemQueryIterator<dynamic>("SELECT * FROM c")
                .ReadNextAsync();
        }
    }
}

使用 ManagedIdentityCredential 的特定语言示例:

.NET

初始化 Azure Cosmos DB 客户端:

CosmosClient client = new CosmosClient("<account-endpoint>", new ManagedIdentityCredential());

然后读取和写入数据

Java

初始化 Azure Cosmos DB 客户端:

CosmosAsyncClient Client = new CosmosClientBuilder().endpoint("<account-endpoint>") .credential(new ManagedIdentityCredential()) .build();

然后,按照这些示例中所述的操作读取和写入数据

Javascript

初始化 Azure Cosmos DB 客户端:

const client = new CosmosClient({ "<account-endpoint>", aadCredentials: new ManagedIdentityCredential() });

然后,按照这些示例中所述的操作读取和写入数据

清理步骤

提示

本文中的步骤可能因开始使用的门户而略有不同。

  1. 登录 Azure 门户

  2. 选择要删除的资源。

  3. 选择“删除”

  4. 出现提示时,确认删除。

后续步骤

详细了解 Azure 资源的托管标识:

详细了解 Azure Cosmos DB: