I love Azure Functions. These days, I have to restrain the tendency to solve every problem with this Swiss army knife.
When designing Azure Function integration with Dynamics 365, one of the immediate questions raised is where to store connection strings, credentials and other sensitive details.
The immediate answer is ‘Not in your code’. So where?
One option is to store sensitive details in the Application Settings store which is ‘encrypted at rest and transmitted over an encrypted channel.’
While this option is quite easy to use, it isn’t considered most secured.
Another option is using Managed Identity with Azure Key Vault service.
With this option, Azure Function App is assigned an AAD identity, which is then authorized to access specific Key Vault secrets.
This option is considered more secured as the Function App is specifically granted access to specific sensitive data, while Application Settings stored data is generally exposed.
In this post, I’ll walkthrough the process of setting and using Managed Identity to Integrate Azure Function with Dynamics 365. In this case, Dynamics 365 access details will be stored in Azure Key Vault.
For the walkthrough, I’ll use the Lead Landing Page scenario, replacing Flow component with Azure Function. Although a bit verbose, the process is quite simple.
- Like most Azure services, Azure Key Vault usage costs money. With Azure Key Vault, any retrieval of secret is paid for. In order to reduce costs, some caching mechanism (which will not be discussed in this post) is in order.
- Have accessible Microsoft Dynamics 365 instance
- Have access to Azure environment with sufficient privileges to create Azure Function and Key Vault store.
- Register App with AAD
Register a new Web App/API in Azure AD with a Client Secret and copy Application Id key and secret to Notepad.
- Add an App User to Dynamics 365
Follow this article: Add a new Application User in Dynamics 365
- Create a Function App
Set Function App details and click ‘Create’
Add a new Function
Select the HTTP trigger option
Click ‘Create’ to complete Function creation
Leave the function code as is for now, we will alter it later on.
- Assign Function App with a Managed Identity
Go to the Function App Platform Features tab and click ‘Identity’
Click the ‘On’ button to assign a System identity and click ‘Save’
Click ‘Yes’ to enable system assigned managed indentity
You can see the newly assigned identity object ID
- Setup Azure Key Vault store
Create a new Azure Key Vault store
Click ‘Create’ at the bottom of the screen
Click ‘Add new’ under the Access policies blade.
In the Add access policy, check Get and List in the Key Management Operations group.
Under the Principal blade, find and select your Function App. Click ‘Select’.
This will grant our Function identity access to the Key Vault secrets.
Next, select a Resource Group for the Key Vault store. Click ‘Create’ to complete Azure Key Vault store creation
- Store secrets in Azure Key Vault
Find the newly created Azure Key Vault store or access it from the dashboard if possible.
Access the Secrets area
Click Secrets and ‘Generate/import’ to generate a new secret
Set secret Name (select a self explanatory name, since once created, you won’t be able to see the actual secret value in the area).
Set the secret string in the Value field. Click ‘Create’.
In this case, the secret I defined is Dynamics Web API URL, similar to https://<ORGNAME>.api.crm<DATACENTERCODE>.dynamics.com/api/data/v9.1/
In the same manner, add additional secrets to hold the applicationId and secret keys you copied after registering an app in AAD (step 1 in this walkthrough).
Click each of the newly created secrets and copy the Secret Identifier, which will be used in the code to access the secret value
- Update Azure Function Code
Go back to the Function created on step 3 above.
Click View Files, add a new project.json file and paste in the following definition. Click ‘Save’.
Go back to the function code and replace the existing code with the code found here (placed in Github for convenience).
This code, triggered by an HTTP request from the Lead landing page, performs the following tasks:
– Receives and parse Lead data
– Extract Dynamics access details from Azure Key Vault
– Use access details to generate an access token
– Create a new Dynamics Lead record using Web API
– Returns operation result to the caller
In the GetDyn365AccessDetails method, replace the URLs for the three keys
dyn365WebAPIURL, dyn365AppIdKVURL, dyn365secretKVURL with the URLs copied on step 6.
Click ‘Get Function URL’ and paste somewhere, as it will be used next
- Hookup Lead Landing Page to Azure Function
Last, create a new HTML page, and copy the HTML found here (placed in Github for convenience).
Find the AzureFunctionRequestURL variable and replace its value with the Azure Function URL copied in the previous step. Save.
To test the solution, run the Lead Landing HTML page. Submitting Lead data should results with a new Lead record in Dynamics 365.
If the flow fails, add the address from which the HTML page is executed to the Azure Function CORS collection to authorize it.