Uso de identidades administradas asignadas por el sistema para acceder a datos de Azure Cosmos DB
SE APLICA A: NoSQL
En este artículo, configurará una solución sólida e independiente de la rotación de claves para acceder a las claves de Azure Cosmos DB mediante identidades administradas y control de acceso basado en roles del plano de datos. En el ejemplo de este artículo se usa Azure Functions, pero puede usar cualquier servicio que admita identidades administradas.
Aprenderá a crear una aplicación de funciones que puede acceder a datos de Azure Cosmos DB sin necesidad de copiar ninguna clave de Azure Cosmos DB. La aplicación de funciones se desencadenará cuando se haga una solicitud HTTP y, a continuación, enumerará todas las bases de datos existentes.
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Una cuenta existente de la API para NoSQL de Azure Cosmos DB. Creación de una cuenta de la API para NoSQL de Azure Cosmos DB
- Una aplicación de funciones existente de Azure Functions. Creación de su primera función en Azure Portal
- Una identidad administrada asignada por el sistema para una aplicación de funciones. Adición de una identidad asignada por el sistema
- Azure Functions Core Tools
- Para seguir los pasos de este artículo, instale la CLI de Azure e inicie sesión en Azure.
Comprobación de requisitos previos
En una ventana de terminal o comando, almacene los nombres de la aplicación de funciones de Azure Functions, la cuenta de Azure Cosmos DB y el grupo de recursos como variables de shell denominadas
functionName
,cosmosName
yresourceGroupName
.# Variable for function app name functionName="msdocs-function-app" # Variable for Azure Cosmos DB account name cosmosName="msdocs-cosmos-app" # Variable for resource group name resourceGroupName="msdocs-cosmos-functions-dotnet-identity"
Nota:
Estas variables se volverán a usar en pasos posteriores. En este ejemplo se supone que el nombre de la cuenta de Azure Cosmos DB es
msdocs-cosmos-app
, el nombre de la aplicación de funciones esmsdocs-function-app
, y el nombre del grupo de recursos esmsdocs-cosmos-functions-dotnet-identity
.Vea las propiedades de la aplicación de funciones mediante el comando
az functionapp show
.az functionapp show \ --resource-group $resourceGroupName \ --name $functionName
Vea las propiedades de la identidad administrada asignada por el sistema para la aplicación de funciones mediante
az webapp identity show
.az webapp identity show \ --resource-group $resourceGroupName \ --name $functionName
Vea las propiedades de la cuenta de Azure Cosmos DB mediante
az cosmosdb show
.az cosmosdb show \ --resource-group $resourceGroupName \ --name $cosmosName
Creación de una API de Azure Cosmos DB para bases de datos NoSQL
En este paso, creará dos bases de datos.
En una ventana de terminal o comando, cree una base de datos
products
conaz cosmosdb sql database create
.az cosmosdb sql database create \ --resource-group $resourceGroupName \ --name products \ --account-name $cosmosName
Cree una base de datos
customers
.az cosmosdb sql database create \ --resource-group $resourceGroupName \ --name customers \ --account-name $cosmosName
Obtención de la API de Azure Cosmos DB para el punto de conexión NoSQL
En este paso, consultará el punto de conexión del documento para la cuenta la API para NoSQL.
Use
az cosmosdb show
con el parámetro query establecido endocumentEndpoint
. Registre el resultado. Usará este valor en un paso posterior.az cosmosdb show \ --resource-group $resourceGroupName \ --name $cosmosName \ --query documentEndpoint cosmosEndpoint=$( az cosmosdb show \ --resource-group $resourceGroupName \ --name $cosmosName \ --query documentEndpoint \ --output tsv ) echo $cosmosEndpoint
Nota:
Esta variable se volverá a usar en un paso posterior.
Concesión de acceso a la cuenta de Azure Cosmos DB
En este paso, asignará un rol a la identidad administrada asignada por el sistema de la aplicación de funciones. Azure Cosmos DB tiene varios roles integrados que se pueden asignar a la identidad administrada para un acceso de plano de control. Para el acceso al plano de datos, creará un rol personalizado con acceso para leer metadatos.
Sugerencia
Para más información sobre la importancia del acceso con privilegios mínimos, vea el artículo Menor exposición de las cuentas con privilegios.
Use
az cosmosdb show
con el parámetro query establecido enid
. Almacene el resultado en una variable de shell denominadascope
.scope=$( az cosmosdb show \ --resource-group $resourceGroupName \ --name $cosmosName \ --query id \ --output tsv ) echo $scope
Nota:
Esta variable se volverá a usar en un paso posterior.
Use
az webapp identity show
con el parámetro query establecido enprincipalId
. Almacene el resultado en una variable de shell denominadaprincipal
.principal=$( az webapp identity show \ --resource-group $resourceGroupName \ --name $functionName \ --query principalId \ --output tsv ) echo $principal
Cree un nuevo archivo JSON con la configuración del nuevo rol personalizado.
{ "RoleName": "Read Azure Cosmos DB Metadata", "Type": "CustomRole", "AssignableScopes": ["/"], "Permissions": [{ "DataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata" ] }] }
Sugerencia
Puede crear un archivo en Azure Cloud Shell mediante
touch <filename>
o el editor integrado (code .
). Para más información, consulte Editor de Azure Cloud ShellUse
az cosmosdb sql role definition create
para crear una nueva definición de rol denominadaRead Azure Cosmos DB Metadata
mediante el objeto JSON personalizado.az cosmosdb sql role definition create \ --resource-group $resourceGroupName \ --account-name $cosmosName \ --body @definition.json
Nota
En este ejemplo, la definición de roles se define en un archivo denominado definition.json.
Use
az role assignment create
para asignar el rolRead Azure Cosmos DB Metadata
a la identidad administrada asignada por el sistema.az cosmosdb sql role assignment create \ --resource-group $resourceGroupName \ --account-name $cosmosName \ --role-definition-name "Read Azure Cosmos DB Metadata" \ --principal-id $principal \ --scope $scope
Acceso mediante programación a las claves de Azure Cosmos DB
Ahora tenemos una aplicación de funciones que tiene una identidad administrada asignada por el sistema con el rol personalizado. La siguiente aplicación de funciones consultará la cuenta de Azure Cosmos DB para obtener una lista de bases de datos.
Cree un proyecto de función local con el parámetro
--dotnet
en una carpeta denominadacsmsfunc
. Cambie el directorio del shell.func init csmsfunc --dotnet cd csmsfunc
Cree una nueva función con el parámetro template establecido en
httptrigger
y name establecido enreaddatabases
.func new --template httptrigger --name readdatabases
Agregue los paquetes NuGet
Azure.Identity
yMicrosoft.Azure.Cosmos
al proyecto de .NET. Compile el proyecto mediantedotnet build
.dotnet add package Azure.Identity dotnet add package Microsoft.Azure.Cosmos dotnet build
Abra el código de función en un entorno de desarrollador integrado (IDE).
Sugerencia
Si usa la CLI de Azure localmente o en Azure Cloud Shell, puede abrir Visual Studio Code.
code .
Reemplace el código del archivo readdatabases.cs por esta implementación de función de ejemplo. Guarde el archivo actualizado.
using System; using System.Collections.Generic; using System.Threading.Tasks; using Azure.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.Cosmos; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace csmsfunc { public static class readdatabases { [FunctionName("readdatabases")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req, ILogger log) { log.LogTrace("Start function"); CosmosClient client = new CosmosClient( accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT", EnvironmentVariableTarget.Process), new DefaultAzureCredential() ); using FeedIterator<DatabaseProperties> iterator = client.GetDatabaseQueryIterator<DatabaseProperties>(); List<(string name, string uri)> databases = new(); while(iterator.HasMoreResults) { foreach(DatabaseProperties database in await iterator.ReadNextAsync()) { log.LogTrace($"[Database Found]\t{database.Id}"); databases.Add((database.Id, database.SelfLink)); } } return new OkObjectResult(databases); } } }
(Opcional) Ejecución de la función localmente
En un entorno local, la clase DefaultAzureCredential
usará varias credenciales locales para determinar la identidad actual. Aunque la ejecución local no es necesaria para el procedimiento, puede desarrollar localmente mediante su propia identidad o una entidad de servicio.
En el archivo local.settings.json, agregue una nueva configuración denominada
COSMOS_ENDPOINT
en el objeto Values. El valor de la configuración debe ser el punto de conexión del documento, que registró anteriormente en esta guía paso a paso.... "Values": { ... "COSMOS_ENDPOINT": "https://msdocs-cosmos-app.documents.azure.com:443/", ... } ...
Nota:
Este objeto JSON se ha abreviado por motivos de concisión. Este objeto JSON también incluye un valor de ejemplo que supone que el nombre de la cuenta es
msdocs-cosmos-app
.Ejecución de la aplicación de funciones
func start
Implementar en Azure
Una vez publicada, la clase DefaultAzureCredential
usará credenciales del entorno o una identidad administrada. En esta guía, la identidad administrada asignada por el sistema se usará como credencial para el constructor CosmosClient
.
Establezca la configuración
COSMOS_ENDPOINT
en la aplicación de funciones ya implementada en Azure.az functionapp config appsettings set \ --resource-group $resourceGroupName \ --name $functionName \ --settings "COSMOS_ENDPOINT=$cosmosEndpoint"
Para implementar la aplicación de funciones en Azure, reutilice la variable
functionName
del shell:func azure functionapp publish $functionName