Modifier

Utiliser des identités managées affectées par le système pour accéder aux données Azure Cosmos DB

S’APPLIQUE À : NoSQL

Dans cet article, vous allez configurer une solution robuste et indépendante de la rotation des clés pour accéder aux clés d’Azure Cosmos DB à l’aide d’identités managées et du contrôle d’accès en fonction du rôle (RBAC) du plan de données. L’exemple de cet article utilise Azure Functions, mais vous pouvez utiliser n’importe quel service qui prend en charge les identités managées.

Vous allez apprendre à créer une application de fonction qui peut accéder aux données Azure Cosmos DB sans avoir à copier les clés d’Azure Cosmos DB. L’application de fonction se déclenche lorsqu’une requête HTTP est effectuée, puis répertorie toutes les bases de données existantes.

Prérequis

  • Compte Azure avec un abonnement actif. Créez un compte gratuitement.

  • Un compte d’API pour NoSQL Azure Cosmos DB existant. Créer un compte d’API pour NoSQL Azure Cosmos DB

  • Application de fonction Azure Functions existante. Créer votre première fonction à l’aide du Portail Azure

  • Azure Functions Core Tools

  • Pour exécuter la procédure indiquée dans cet article, installez Azure CLI et connectez-vous à Azure.

    Vérification du prérequis

    1. Dans une fenêtre de terminal ou de commande, stockez les noms de votre application de fonction Azure Functions, de votre compte Azure Cosmos DB et de votre groupe de ressources en tant que variable d’interpréteur de commandes nommées functionName, cosmosName et resourceGroupName.

      # 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"
      

      Notes

      Ces variables seront réutilisées dans les étapes ultérieures. Cet exemple suppose que le nom de votre compte Azure Cosmos DB est msdocs-cosmos-app, le nom de votre application de fonction msdocs-function-app et le nom de votre groupe de ressources msdocs-cosmos-functions-dotnet-identity.

    2. Affichez les propriétés de l’application de fonction à l’aide de la commande az functionapp show.

      az functionapp show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    3. Affichez les propriétés de l’identité managée affectée par le système pour votre application de fonction à l’aide de az webapp identity show.

      az webapp identity show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    4. Affichez les propriétés du compte Azure Cosmos DB à l’aide de az cosmosdb show.

      az cosmosdb show \
          --resource-group $resourceGroupName \
          --name $cosmosName
      

Créer des bases de données d’API pour NoSQL Azure Cosmos DB

Au cours de cette étape, vous allez créer deux bases de données.

  1. Dans une fenêtre de terminal ou de commande, créez une base de données products à l’aide de az cosmosdb sql database create.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name products \
        --account-name $cosmosName
    
  2. Créez une base de données customers.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name customers \
        --account-name $cosmosName
    

Obtenir un point de terminaison d’API pour NoSQL Azure Cosmos DB

Au cours de cette étape, vous allez interroger le point de terminaison de document pour le compte d’API pour NoSQL.

  1. Utilisez az cosmosdb show avec le paramètre query défini sur documentEndpoint. Enregistrez le résultat. Vous utiliserez cette valeur ultérieurement.

    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
    

    Notes

    Cette variable sera réutilisée dans une étape ultérieure.

Accorder l’accès à votre compte Azure Cosmos DB

Dans cette étape, vous allez attribuer un rôle à l’identité managée affectée par le système de votre application de fonction. Azure Cosmos DB a plusieurs rôles intégrés que vous pouvez attribuer à l’identité managée pour l’accès au plan de contrôle. Pour l’accès au plan de données, vous allez créer un rôle personnalisé avec l’accès pour lire les métadonnées.

Conseil

Pour plus d’informations sur l’importance de l’accès avec un privilège minimum, consultez l’article Exposition réduite des comptes privilégiés.

  1. Utilisez az cosmosdb show avec le paramètre query défini sur id. Stockez le résultat dans une variable d’interpréteur de commandes nommée scope.

    scope=$(
        az cosmosdb show \
            --resource-group $resourceGroupName \
            --name $cosmosName \
            --query id \
            --output tsv
    )
    
    echo $scope
    

    Notes

    Cette variable sera réutilisée dans une étape ultérieure.

  2. Utilisez az webapp identity show avec le paramètre query défini sur principalId. Stockez le résultat dans une variable d’interpréteur de commandes nommée principal.

    principal=$(
        az webapp identity show \
            --resource-group $resourceGroupName \
            --name $functionName \
            --query principalId \
            --output tsv
    )
    
    echo $principal
    
  3. Créez un fichier JSON avec la configuration du nouveau rôle personnalisé.

    {
        "RoleName": "Read Azure Cosmos DB Metadata",
        "Type": "CustomRole",
        "AssignableScopes": ["/"],
        "Permissions": [{
            "DataActions": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata"
            ]
        }]
    }
    

    Conseil

    Vous pouvez créer un fichier dans Azure Cloud Shell à l’aide de touch <filename> ou de l’éditeur intégré (code .). Pour plus d’informations, consultez Éditeur Azure Cloud Shell

  4. Utilisez az cosmosdb sql role definition create pour créer une définition de rôle nommée Read Azure Cosmos DB Metadata à l’aide de l’objet JSON personnalisé.

    az cosmosdb sql role definition create \
        --resource-group $resourceGroupName \
        --account-name $cosmosName \
        --body @definition.json
    

    Notes

    Dans cet exemple, la définition de rôle est définie dans un fichier nommé definition.json.

  5. Utilisez az role assignment create pour attribuer le rôle Read Azure Cosmos DB Metadata à l’identité managée affectée par le système.

    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
    

Accéder par programme aux clés d’Azure Cosmos DB

Nous disposons maintenant d’une application de fonction qui a une identité managée affectée par le système avec le rôle personnalisé. L’application de fonction suivante interroge le compte Azure Cosmos DB pour obtenir la liste des bases de données.

  1. Créez un projet de fonction local avec le paramètre --dotnet dans un dossier nommé csmsfunc. Modifier le répertoire de votre interpréteur de commandes

    func init csmsfunc --dotnet
    
    cd csmsfunc
    
  2. Créez une fonction avec le paramètre template défini sur httptrigger et name défini sur readdatabases.

    func new --template httptrigger --name readdatabases
    
  3. Ajoutez le package NuGet Azure.Identity et Microsoft.Azure.Cosmos au projet .NET. Générez le projet à l’aide de dotnet build.

    dotnet add package Azure.Identity
    
    dotnet add package Microsoft.Azure.Cosmos
    
    dotnet build
    
  4. Ouvrez le code de fonction dans un environnement de développement intégré (IDE).

    Conseil

    Si vous utilisez Azure CLI localement ou dans Azure Cloud Shell, vous pouvez ouvrir Visual Studio Code.

    code .
    
  5. Remplacez le code dans le fichier readdatabases.cs par cet exemple d’implémentation de fonction. Enregistrez le fichier mis à jour.

    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);
            }
        }
    }
    

(Facultatif) Exécuter la fonction localement

Dans un environnement local, la classe DefaultAzureCredential utilise différentes informations d’identification locales pour déterminer l’identité actuelle. Si l’exécution locale n’est pas obligatoire pour la procédure, vous pouvez développer localement à l’aide de votre propre identité ou d’un principal de service.

  1. Dans le fichier local.settings.json, ajoutez un nouveau paramètre nommé COSMOS_ENDPOINT dans l’objet Values. La valeur du paramètre doit être le point de terminaison de document que vous avez enregistré précédemment dans ce guide pratique.

    ...
    "Values": {
        ...
        "COSMOS_ENDPOINT": "https://msdocs-cosmos-app.documents.azure.com:443/",
        ...
    }
    ...
    

    Notes

    Cet objet JSON a été raccourci à des fins de concision. Cet objet JSON inclut également un exemple de valeur qui suppose que le nom de votre compte est msdocs-cosmos-app.

  2. Exécuter l’application de fonction

    func start
    

Déploiement sur Azure

Une fois publiée, la classe DefaultAzureCredential utilise les informations d’identification de l’environnement ou d’une identité managée. Pour ce guide, l’identité managée affectée par le système sera utilisée comme informations d’identification pour le constructeur CosmosClient.

  1. Définissez le paramètre COSMOS_ENDPOINT sur l’application de fonction déjà déployée dans Azure.

    az functionapp config appsettings set \
        --resource-group $resourceGroupName \
        --name $functionName \
        --settings "COSMOS_ENDPOINT=$cosmosEndpoint"
    
  2. Déployez votre application de fonction dans Azure en réutilisant la variable d’interpréteur de commandes functionName :

    func azure functionapp publish $functionName
    
  3. Testez votre fonction dans le portail Azure.