Going passwordless with Azure Functions and Cosmos DB
    • Dark
      Light
    • PDF

    Going passwordless with Azure Functions and Cosmos DB

    • Dark
      Light
    • PDF

    Article Summary

    #ServerlessTips - Azure Functions
    Author: Jan De Vries Microsoft Azure MVP

    What can be better is combining the two.

    As it happens, you can. The libraries to connect in a passwordless fashion to several repositories in Azure are available. This means we can rely on RBAC of the services with the Managed Identity of our Azure Functions. Take, for example, Storage Account Blobs, Queues and even Service Bus! However, this tip focuses on Azure Cosmos DB.

    To work in a passwordless fashion with Cosmos DB, you need to use the Elastic Premium plan at this moment. This does influence the price of your Azure Functions solution but gives you great features in return.

    Using the Managed Identity of your Function App is supported in the v4 extension of Azure Cosmos DB, so you need to install this in your solution. Afterwards, the only thing you need to do in the settings is adding the endpoint to Cosmos DB, like in the following sample.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "FunctionsPlaygroundRepository__accountEndpoint": "https://my-cosmos-repository.documents.azure.com:443/"
      }
    }
    
    

    The endpoint to Cosmos DB is stored in the value of FunctionsPlaygroundRepository__accountEndpoint. The __accountEndpoint postfix is a convention necessary for the library to pick it up. Everything before this postfix is the ‘key’ necessary in the code.
    You are now able to use the Cosmos DB input binding in an Azure Function, like the following

    FunctionName(nameof(GetUsers))]
    public async IAsyncEnumerable<User> GetUsers(
        [HttpTrigger(AuthorizationLevel.Function, "GET")] 
        HttpRequest req,
        [CosmosDB(Connection = "FunctionsPlaygroundRepository")]
        CosmosClient client)
    {
        // Your logic over here
    }
    
    

    Or an output binding like so

    [FunctionName(nameof(PostUser))]
    public IActionResult PostUser(
        [HttpTrigger(AuthorizationLevel.Function, "POST")]
        HttpRequest req,
        [CosmosDB(
            databaseName: "Music",
        containerName: "Users",
            Connection = "FunctionsPlaygroundRepository")]
        out dynamic newUser)
    {
        // Your logic over here
        newUser = new { userPayload.Firstname, userPayload.Lastname, partitionKey = userPayload.PartitionKey, id = userPayload.Id };
    }
    
    

    Of course, for this to work, the Managed Identity feature of the Function App needs to be turned on and this identity needs to be granted permission on Cosmos DB. As this feature is in preview now, there isn’t support for the Azure Portal, yet. The Azure CLI has been updated to assign these roles, which you can find in the documentation.

    For reference, here’s a sample script to assign the appropriate roles to your identities

    $resourceGroupName='<myResourceGroup>'
    $accountName='<myCosmosAccount>'
    # Cosmos DB Built-in Data Reader: 00000000-0000-0000-0000-000000000001
    # Cosmos DB Built-in Data Contributor: 00000000-0000-0000-0000-000000000002
    $readOnlyRoleDefinitionId = '<roleDefinitionId>'
    $principalId = '<aadPrincipalIdOfYourManagedIdentity>'
    az cosmosdb sql role assignment create --account-name $accountName --resource-group $resourceGroupName --scope "/" --principal-id $principalId --role-definition-id $readOnlyRoleDefinitionId
    
    

    If successful, you’ll get a JSON output stating the role has been assigned.

    Be sure to start using this ‘passwordless feature as soon as you can. Not only for Cosmos DB, but also for all of the other supported repositories!

    Azure-functions.png


    Was this article helpful?