As I'm preparing for the Azure Developer Certificate (AZ-204) I thought it would be a good idea to write blog posts about some topics which could extend the functionalities of Microsoft Power Platform or Dynamics 365 CE with the power of Azure. Therefore, there will be a series of blog posts that showcase how Azure components are set up to be used. In this article I'm writing about Azure Functions and will answer the questions about what they are and how to connect them to Dataverse environments. In upcoming articles, I will dive deeper into use cases where Azure Functions may be a good choice for extending Dataverse. But this article will only focus on connecting to Dataverse from an external service and not on how to call an Azure Function from within Dataverse (Hint: Webhook).
What are Azure Functions?
Azure Functions is a Function as Service (FaaS) offering from Microsoft which allows developers to focus on writing code and not dealing with the underlying infrastructure like server-setups or Internet Information Services (IIS). On a higher level you could argue that Azure Functions is a serverless cloud service because the whole infrastructure is abstracted away, and you only pay for the execution of functions. Azure Functions are an event driven services where an Input-Trigger causes the function to execute. A triggered Function can receive input-data (Input-Bindings). Those are data sources that pass information into the function when triggered. After the function was executed successfully it can output data (Output-Bindings) into one or more data sinks. There is a wide variety of available Input- and Output-Bindings which can trigger a function or be used inside of a function (for example: Azure Service Bus, Timer, Cosmos DB). For more information see the official documentation. The container for one Azure Function is the so-called Azure Function App, which defines underlying settings for Hosting, Runtime and other global settings. So, a Function App can contain several Functions which thereby share some global settings.
Prerequisites to get started
Before we get started to trying out how to integrate Dataverse with Azure Functions there are some steps which you need to process before:
- Create appregistration in Microsoft Entra Id: First it is necessary to create an app registration inside Micrsoft Entra Id. Therefore, open Microsoft Entra Id in the Azure Portal (portal.azure.com), click on the Add-Button and choose app registration. On the next page choose a suitable name for your app registration, keep the default values, and click create. Finally, you need to grant api permissions to your app registrations. There in the left navigation of Microsoft Entra Id expand the Manage-Area and click on App registrations. In the list choose the newly created once and again navigate to the Manage-Area and choose API permissions. Click on Add a permission and choose Dynamics CRM. The last step is to add a secret to your app registration. Click on Certificates & Secrets in the manage area of your left-hand navigation. Add a new client secret and store the secret value in your password manager. Your app registration is now ready to be used.
- Add Application User to your Dataverse Environment: As a second step you should register your newly created app registration as an application user in your Dataverse environment. Therefore open the power platform admin center (admin.powerplatform.microsoft.com), click on Environments on the left-side navigation and in the list of environments choose the one you want to work with. In the Access-Area, which is located on the right side of the window, click on 'Show All Users' and then (!IMPORTANT) switch to the list of application users. Now click on Add new app user. Add your app registration, which was created in the previous step, choose the relevant business unit, and assign a security role to your app. As a reminder: The least needed security rights should be chosen and not the system administrator! 😉
After succesfully completing the two steps you are up and running to connect Azure Functions to Dataverse.
Connecting to Dataverse with ServiceClient and Appregistration
Side node: The code snippets below uses early bound entities. I was curious, whether it is possible to use them inside of azure functions. So far, it looks like its working. The classes were generated with the Early Bound Generator, written by Daryl LaBar. I don't know if it's a good idea to use them in azure functions, but I don't see any reason not to. I highly appreciate any feedback if you have concerns regarding the usage.
Connect to Dataverse using ServiceClient and appsettings
Connect to Dataverse using ServiceClient, appsettings and Azure Key Vault
First step to integrate Azure Key Vault is to create the Azure resource (Key Vault) and add your secure information (app secret, CRM Url) to it. For using the Key Vault secret locally in your Function App Project add a new entry to the local appsettings.
Recap and Outlook
This article showcased how to connect to a dataverse instance by using Azure Functions and the ServiceClient class from the nuget package "Microsoft.PowerPlatform.Dataverse.Client". We have learned three different ways to store relevant connection information:
- Store the connection information hard coded.
- Store the connection information in appsettings.
- Store the connection information in Key Vault and access them via appsettings
The most secure approach to store this information is by using Azure Key Vault. We should by all
means avoid storing connecting information hard coded. This is not only a security risk but also
avoids using CI/CD-practices.
In my next article of this series I will introduce managed identities and showcase how to use
them to connect to dataverse from within an Azure Function. Since I am far from being the best
developer, the code written in this article could be improved if necessary. Therefore, I am
always grateful for feedback.