Skip to content

Latest commit

 

History

History
74 lines (43 loc) · 5.49 KB

File metadata and controls

74 lines (43 loc) · 5.49 KB

Durable Azure Function as a Deployment Target

Introduction

Azure Functions and Azure Durable Functions provide access to a serverless solution for microservices implementation. They support various programming languages, including Python and C#, and both real-time and long-running services can be implemented using a unified Azure environment.

The primary goal of this document is to demonstrate a way to setup an Azure Function with abilities to interact with Azure OpenAI, Azure Storage and other services using keyless approach.

User-Assigned Managed Identity

It is recommended to avoid key storage and sharing during the development process. For local testing, Entra ID integration can be utilized with the engineer's credentials. However, when deploying a service, it may not always be feasible to use the user's Entra credentials, particularly if the service is part of a complex system.

User-Assigned Managed Identity can be a solution to the problem mentioned above. It allows us to create a system user with a set of permissions, which can be assigned to Azure services to provide a unique execution context where no keys are needed. Potentially, System Managed Identity can be used instead, but it cannot be shared across resources if needed.

In order to setup an Azure Function to work under User-Assigned Managed Identity we need to create it. It can be done through the portal, Azure CLI, Resource Manager and so on. In any case, it's a straightforward process that requires picking a name, which should be noted along with the associated client ID that will be assigned right after creation.

User Managed Identity

Roles

Once a User-Assigned Managed Identity has been created, it's possible to assign the needed roles to it. The set of roles might vary depending on your needs, but we will enumerate the roles required for the current template in this repository.

  • Azure Storage roles: All Azure Functions have associated Azure Storage account, and Durable Azure Functions use Blobs, Tables and Queues from it. It means that User-Assigned Managed Identity should have access to all three entities to make sure that Azure Functions can operate. Storage Blob Data Contributor, Storage Table Data Contributor and Storage Queue Data Contributor should be assigned.

  • Azure Open AI: The custom skills use Azure OpenAI models to generate embeddings. Therefore, Cognitive Services OpenAI User should be assigned.

Azure Functions Parameters

Once we have User-Assigned Managed Identity it's important to setup Azure Function to use it for internal needs (got access to the associated storage account). Pay attention, that portal doesn't support User-Assigned Managed Identity in the deployment wizard for Azure Functions. Therefore, App Settings page will contain some records that use connection strings and keys - these records should be deleted.

Azure Settings to Delete

Additional records should be added to App Settings of Azure Functions:

  • AzureWebJobsStorage__accountname: a storage account name of the associated storage account.
  • AzureWebJobsStorage__credential: managedidentity value should be here.
  • AzureWebJobsStorage__clientId: client id of the created User-Assigned Managed Identity should be in this field.

New App Settings

Once all the values are provided Azure Functions will be able to communicate with the associated storage account with no explicit connection strings.

Function Authentication

The custom skillset functions use AuthLevel.FUNCTION, which means callers must supply a valid function key. Function keys are automatically generated by Azure Functions and can be retrieved programmatically using the Azure Management SDK. The deploy_azure_functions.py and run_functions.py scripts retrieve the function key as part of the deployment and validation process.

Deploying Functions

Functions are deployed using the Azure CLI az functionapp deployment source config-zip command with the --build-remote true flag, which triggers a remote build on the Azure App Service. This eliminates the need for ENABLE_ORYX_BUILD or SCM_DO_BUILD_DURING_DEPLOYMENT app settings.

Obtaining Credentials in Code

Finally, we need to make sure that Azure Functions can use our identity in code to communicate with other services.

First, we need to explicitly allow to use our identity from code. It can be done using Identity tab in the Settings of the Function App.

Adding identity

Second, our code should specify which identity to use since several different identities can be assigned to the service. It can be done like this:

credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id)

As you can see DefaultAzureCredential class should take managed_identity_client_id, and you can read this parameter from AzureWebJobsStorage__clientId if you share the same identity.