시스템 할당 관리 ID를 사용하여 Azure Cosmos DB 데이터에 액세스

적용 대상: NoSQL

이 문서에서는 관리 ID데이터 평면 역할 기반 액세스 제어를 사용하여 Azure Cosmos DB 키에 액세스할 수 있도록 강력한 키 순환과 무관한 솔루션을 설정합니다. 이 문서의 예에서는 Azure Functions를 사용하지만 관리 ID를 지원하는 모든 서비스를 사용할 수 있습니다.

Azure Cosmos DB 키를 복사할 필요 없이 Azure Cosmos DB 데이터에 액세스할 수 있는 함수 앱을 만드는 방법을 알아봅니다. 함수 앱은 HTTP 요청이 수행될 때 트리거된 다음, 모든 기존 데이터베이스를 나열합니다.

필수 조건

  • 활성 구독이 있는 Azure 계정. 체험 계정을 만듭니다.

  • 기존 Azure Cosmos DB API for NoSQL 계정. Azure Cosmos DB NoSQL용 API 계정 만들기

  • 기존 Azure Functions 함수 앱. Azure Portal에서 첫 번째 함수 만들기

  • Azure Functions Core Tools

  • 이 문서의 단계를 수행하려면 Azure CLI를 설치하고 Azure에 로그인합니다.

    필수 구성 요소 확인

    1. 터미널 또는 명령 창에서 Azure Functions 함수 앱, Azure Cosmos DB 계정 및 리소스 그룹의 이름을 functionName, cosmosNameresourceGroupName이라는 셸 변수로 저장합니다.

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

      참고 항목

      이러한 변수는 이후 단계에서 다시 사용됩니다. 이 예제에서는 Azure Cosmos DB 계정 이름이 msdocs-cosmos-app, 함수 앱 이름이 msdocs-function-app, 리소스 그룹 이름이 msdocs-cosmos-functions-dotnet-identity라고 가정합니다.

    2. az functionapp show 명령을 사용하여 함수 앱의 속성을 봅니다.

      az functionapp show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    3. az webapp identity show를 사용하여 함수 앱에 대한 시스템이 할당한 관리 ID의 속성을 봅니다.

      az webapp identity show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    4. az cosmosdb show를 사용하여 Azure Cosmos DB 계정의 속성을 봅니다.

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

Azure Cosmos DB API for NoSQL 데이터베이스 만들기

이 단계에서는 두 개의 데이터베이스를 만듭니다.

  1. 터미널 또는 명령 창에서 az cosmosdb sql database create를 사용하여 새 products 데이터베이스를 만듭니다.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name products \
        --account-name $cosmosName
    
  2. customers 데이터베이스를 만듭니다.

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

Azure Cosmos DB API for NoSQL 엔드포인트 가져오기

이 단계에서는 API for NoSQL 계정에 대한 문서 엔드포인트를 쿼리합니다.

  1. query 매개 변수를 documentEndpoint로 설정하고 az cosmosdb show를 사용합니다. 결과를 기록합니다. 이후 단계에서 이 값을 사용합니다.

    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
    

    참고 항목

    이 변수는 이후 단계에서 다시 사용됩니다.

Azure Cosmos DB 계정에 대한 액세스 권한 부여

이 단계에서는 함수 앱의 시스템 할당 관리 ID에 역할을 할당합니다. Azure Cosmos DB에는 컨트롤 플레인 액세스를 위해 관리 ID에 할당할 수 있는 여러 기본 제공 역할이 있습니다. 데이터 평면 액세스의 경우 메타데이터를 읽을 수 있는 액세스 권한이 있는 새 사용자 지정 역할을 만듭니다.

최소 권한 액세스의 중요성에 대한 자세한 내용은 권한 있는 계정 노출 감소 문서를 참조하세요.

  1. query 매개 변수를 id로 설정하고 az cosmosdb show를 사용합니다. scope라는 셸 변수에 결과를 저장합니다.

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

    참고 항목

    이 변수는 이후 단계에서 다시 사용됩니다.

  2. query 매개 변수를 principalId로 설정하고 az webapp identity show를 사용합니다. principal라는 셸 변수에 결과를 저장합니다.

    principal=$(
        az webapp identity show \
            --resource-group $resourceGroupName \
            --name $functionName \
            --query principalId \
            --output tsv
    )
    
    echo $principal
    
  3. 새 사용자 지정 역할의 구성을 사용하여 새 JSON 파일을 만듭니다.

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

    touch <filename> 또는 기본 제공 편집기(code .)를 사용하여 Azure Cloud Shell에서 파일을 만들 수 있습니다. 자세한 내용은 Azure Cloud Shell 편집기를 참조하세요.

  4. az cosmosdb sql role definition create를 통해 사용자 지정 JSON 개체를 사용하여 Read Azure Cosmos DB Metadata라는 새 역할 정의를 만듭니다.

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

    참고 항목

    이 예제에서 역할 정의는 definition.json이라는 파일에 정의되어 있습니다.

  5. az role assignment create를 사용하여 Read Azure Cosmos DB Metadata 역할을 시스템이 할당한 관리 ID에 할당합니다.

    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
    

프로그래밍 방식으로 Azure Cosmos DB 키에 액세스

이제 사용자 지정 역할이 있는 시스템 할당 관리 ID가 있는 함수 앱이 있습니다. 다음 함수 앱은 Azure Cosmos DB 계정의 데이터베이스 목록을 쿼리합니다.

  1. csmsfunc라는 폴더에서 --dotnet 매개 변수를 사용하여 로컬 함수 프로젝트를 만듭니다. 셸의 디렉터리 변경

    func init csmsfunc --dotnet
    
    cd csmsfunc
    
  2. template 매개 변수를 httptrigger로 설정하고 namereaddatabases로 설정하여 새 함수를 만듭니다.

    func new --template httptrigger --name readdatabases
    
  3. Azure.IdentityMicrosoft.Azure.Cosmos NuGet 패키지를 .NET 프로젝트에 추가합니다. dotnet build를 사용하여 프로젝트를 빌드합니다.

    dotnet add package Azure.Identity
    
    dotnet add package Microsoft.Azure.Cosmos
    
    dotnet build
    
  4. IDE(통합 개발 환경)에서 함수 코드를 엽니다.

    로컬 또는 Azure Cloud Shell에서 Azure CLI를 사용하는 경우 Visual Studio Code를 열 수 있습니다.

    code .
    
  5. readdatabases.cs 파일의 코드를 이 샘플 함수 구현으로 바꿉니다. 업데이트된 파일을 저장합니다.

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

(선택 항목) 함수를 로컬에서 실행

로컬 환경에서 DefaultAzureCredential 클래스는 다양한 로컬 자격 증명을 사용하여 현재 ID를 확인합니다. 로컬 실행은 방법이 필요하지 않지만 고유한 ID 또는 서비스 주체를 사용하여 로컬에서 개발할 수 있습니다.

  1. local.settings.json 파일의 Values 개체에 COSMOS_ENDPOINT라는 새 설정을 추가합니다. 설정 값은 이 방법 가이드의 앞부분에서 기록한 문서 엔드포인트여야 합니다.

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

    참고 항목

    이 JSON 개체는 간단히 나타내기 위해 축약했습니다. 이 JSON 개체에는 계정 이름이 msdocs-cosmos-app이라고 가정하는 샘플 값도 포함됩니다.

  2. 함수 앱 실행

    func start
    

Deploy to Azure

게시된 후 DefaultAzureCredential 클래스는 환경 또는 관리 ID의 자격 증명을 사용합니다. 이 가이드에서 시스템이 할당한 관리 ID는 CosmosClient 생성자의 자격 증명으로 사용됩니다.

  1. Azure에 이미 배포된 함수 앱에서 COSMOS_ENDPOINT 설정을 지정합니다.

    az functionapp config appsettings set \
        --resource-group $resourceGroupName \
        --name $functionName \
        --settings "COSMOS_ENDPOINT=$cosmosEndpoint"
    
  2. functionName 셸 변수를 다시 사용하여 함수 앱을 Azure에 배포합니다.

    func azure functionapp publish $functionName
    
  3. Azure Portal에서 함수를 테스트합니다.