How to use managed identities to connect to Azure Cosmos DB from an Azure virtual machine

In this article, we set up a virtual machine to use managed identities to connect to Azure Cosmos DB. Azure Cosmos DB is a fully managed NoSQL database for modern app development. Managed identities for Azure resources allow your applications to authenticate when accessing services that support Azure AD authentication using an identity managed by Azure.

Prerequisites

  • A basic understanding of Managed identities. If you would like to learn more about managed identities for Azure resources before you continue, review the managed identities overview.
  • You must have an Azure account with an active subscription. Create an account for free.
  • You may need either PowerShell or the CLI.
  • Visual Studio Community Edition or some other development environment of your choosing.

Create a resource group

Create a resource group called mi-test. We'll use this resource group for all resources used in this tutorial.

Create an Azure VM with a managed identity

For this tutorial, you need an Azure virtual machine(VM). Create a virtual machine with a system-assigned managed identity enabled called mi-vm-01. You may also create a user-assigned managed identity called mi-ua-01 in the resource group we created earlier (mi-test). If you use a user-assigned managed identity, you can assign it to a VM during creation.

Create a VM with a system-assigned managed identity

To create an Azure VM with the system-assigned managed identity enabled, your account needs the Virtual Machine Contributor role assignment. No other Azure AD role assignments are required.

  • From the Azure portal search for virtual machines.
  • Choose Create
  • In the Basics tab, provide the required information.
  • Choose Next: Disks >
  • Continue filling out information as needed and in the Management tab find the Identity section and check the box next to System assigned managed identity

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

For more information, review the Azure virtual machines documentation:

Create a VM with a user-assigned managed identity

The steps below show you how to create a virtual machine with a user-assigned managed identity configured.

Today, the Azure portal doesn't support assigning a user-assigned managed identity during the creation of a VM. You should create a virtual machine and then assign a user assigned managed identity to it.

Configure managed identities for Azure resources on a VM using the Azure portal

Create an Azure Cosmos DB account

Now that we have a VM with either a user-assigned managed identity or a system-assigned managed identity we need an Azure Cosmos DB account available where you have administrative rights. If you need to create an Azure Cosmos DB account for this tutorial, the Azure Cosmos DB quickstart provides detailed steps on how to do that.

Note

Managed identities may be used to access any Azure resource that supports Azure Active Directory authentication. This tutorial assumes that your Azure Cosmos DB account will be configured as shown below.

Setting Value Description
Subscription Subscription name Select the Azure subscription that you want to use for this Azure Cosmos DB account.
Resource Group Resource group name Select mi-test, or select Create new, then enter a unique name for the new resource group.
Account Name A unique name Enter a name to identify your Azure Cosmos DB account. Because documents.azure.com is appended to the name that you provide to create your URI, use a unique name.

The name can only contain lowercase letters, numbers, and the hyphen (-) character. It must be between 3-44 characters in length.
API The type of account to create Select Azure Cosmos DB for NoSQL to create a document database and query by using SQL syntax.

Learn more about the SQL API.
Location The region closest to your users Select a geographic location to host your Azure Cosmos DB account. Use the location that is closest to your users to give them the fastest access to the data.

Note

If you are testing you may want to apply Azure Cosmos DB free tier discount. With the Azure Cosmos DB free tier, you will get the first 1000 RU/s and 25 GB of storage for free in an account. Learn more about free tier. Keep in mind that for the purpose of this tutorial this choice makes no difference.

Grant access

At this point, we should have both a virtual machine configured with a managed identity and an Azure Cosmos DB account. Before we continue, we need to grant the managed identity a couple of different roles.

  • First grant access to the Azure Cosmos DB management plane using Azure RBAC. The managed identity needs to have the DocumentDB Account Contributor role assigned to create Databases and containers.

  • You also need to grant the managed identity a contributor role using Azure Cosmos DB RBAC. You can see specific steps below.

Note

We will use the Cosmos DB Built-in Data contributor role. To grant access, you need to associate the role definition with the identity. In our case, the managed identity associated with our virtual machine.

At this time there is no role assignment option available in the Azure portal

Access data

Getting access to Azure Cosmos DB using managed identities may be achieved using the Azure.identity library to enable authentication in your application. You can call ManagedIdentityCredential directly or use DefaultAzureCredential.

The ManagedIdentityCredential class attempts to authentication using a managed identity assigned to the deployment environment. The DefaultAzureCredential class goes through different authentication options in order. The second authentication option that DefaultAzureCredential attempts is Managed identities.

In the example shown below, you create a database, a container, an item in the container, and read back the newly created item using the virtual machine's system assigned managed identity. If you want to use a user-assigned managed identity, you need to specify the user-assigned managed identity by specifying the managed identity's client ID.

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

To use the sample below, you need to have the following NuGet packages:

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

In addition to the NuGet packages above, you also need to enable Include prerelease and then add 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)
        {
            var subscriptionId = "Your subscription ID";
            var resourceGroupName = "You resource group";
            var accountName = "Cosmos DB Account name";
            var databaseName = "mi-test";
            var containerName = "container01";

            var tokenCredential = new DefaultAzureCredential();

            // create the management clientSS
            var managementClient = new CosmosDBManagementClient(subscriptionId, tokenCredential);

            // create the data client
            var dataClient = new CosmosClient("https://[Account].documents.azure.com:443/", tokenCredential);

            // create a new database 
            var createDatabaseOperation = await managementClient.SqlResources.StartCreateUpdateSqlDatabaseAsync(resourceGroupName, accountName, databaseName,
                new SqlDatabaseCreateUpdateParameters(new SqlDatabaseResource(databaseName), new CreateUpdateOptions()));
            await createDatabaseOperation.WaitForCompletionAsync();

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


            // create a new item 
            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
            var pointReadResult = await dataClient.GetContainer(databaseName, containerName)
                .ReadItemAsync<dynamic>(id, new PartitionKey(partitionKey));


            // run a query
            await dataClient.GetContainer(databaseName, containerName)
                .GetItemQueryIterator<dynamic>("SELECT * FROM c")
                .ReadNextAsync();
        }
    }
}

Language-specific examples using ManagedIdentityCredential:

.NET

Initialize your Azure Cosmos DB client:

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

Then read and write data.

Java

Initialize your Azure Cosmos DB client:

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

Then read and write data as described in these samples

JavaScript

Initialize your Azure Cosmos DB client:

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

Then read and write data as described in these samples

Clean up steps

  1. In the portal, select the resource you want to delete.

  2. Select Delete.

  3. When prompted, confirm the deletion.

Next steps

Learn more about managed identities for Azure resources:

Learn more about Azure Cosmos DB: