Dataverse healthcare APIs: Use Healthcare data pipeline template to deploy Azure Logic Apps
This article provides a step-by-step guide for using a template to deploy a group of Azure Logic Apps that ingest FHIR data into Dataverse healthcare APIs, Azure Health Data Services, or both. This solution works as an enterprise-ready Logic App flow that serves as a relay between Azure Health Data Services and Dataverse healthcare APIs. The flow also manages retry logic and exception handling. It relies on an Azure Blob Storage trigger rather than the HTTP trigger used in the manual configuration.
This workflow is available for deployment as an Azure Resource Manager (ARM) template titled Healthcare data pipeline template. You can deploy the template from Microsoft Cloud Solution Center. This offering is a more robust and supported solution provided by Microsoft Cloud for Healthcare. You need to set up some basic manual configuration after deploying the template.
Note
This Logic App flow is provided as an entry point for inbound Electronic Health Record (EHR) data, ensuring that FHIR data is posted to the correct services. It isn't a final solution in its current state, and is intended to be updated based on your business needs.
These logic app services aren't required to post FHIR data to the Dataverse healthcare API endpoints. You can choose to build your own solution to relay data from your EHR to the APIs and handle the responses.
The logic app services rely on an Azure Blob Storage trigger to trigger asynchronous processing of the bundles posted to a configurable storage location. This option handles heavier loads for enterprise use-cases and includes extra exception handling steps. However, you should conduct thorough testing with your expected daily loads.
After deployment, you can extend the logic apps to suit your particular system needs.
Important
This ARM template is only compatible with Microsoft Cloud for Healthcare 2022 release wave 2 and later versions. For older versions, delete the Set requestBody to FHIR response on success action before triggering a run.
The configuration includes the following steps:
Prerequisites
Ensure that your environment meets the following requirements before you deploy the template:
- An Azure account and subscription. If you don't have a subscription, sign up for a free Azure account before you begin.
- An Azure resource group configured with appropriate permissions to create new resources, or a Contributor role to create new resource groups.
- Access within the resource group to create resources and assign Azure roles.
- Adherence to security guidelines outlined by Azure administrators and organization policy.
Design
The following diagram illustrates the design of the pipeline deployed through the template:
The ARM template deploys several modularized Logic Apps. It includes the following three logic app services:
Logic App | Description |
---|---|
Process FHIR Bundle | The first logic app instance triggered when a bundle is uploaded to the blob storage. This logic app determines whether to post the bundle to FHIR or directly to Dataverse. |
Send Bundle to FHIR | The second logic app triggered from the Process FHIR Bundle logic app, when you choose to post the bundle to FHIR. This logic app processes the request bundle and posts it to the FHIR server. After this logic app posts the bundle to the FHIR server, it relays the bundle to the next logic app Send Bundle to Dataverse for further processing. |
Send Bundle to Dataverse | The final logic app triggered either from the Process FHIR Bundle or Send Bundle to FHIR logic app. It processes the request bundle and posts the bundle to Dataverse. It also handles the bundles container clean-up by moving the request bundle to either the bundleserror or bundlesarchive container. |
Template parameters
Parameter | Description |
---|---|
Resource location | The Azure region for resource creation. This parameter value defaults to the region used to create the resource group. |
Dataverse URL | The URL of your Microsoft Cloud for Healthcare Dataverse environment. For example, https://*orgname*.crm.dynamics.com |
Post to FHIR server | A boolean value. If set to true, the bundle is posted to the FHIR server. |
FHIR server URL | The URL of your FHIR server. For example, https://*fhirserver*.azurewebsites.net You only require this parameter if you want to post to the FHIR server before posting to the Dataverse upsert API endpoint. |
Unique value | The unique string used to generate resource names. This value defaults to the uniqueString function. You can override this value if needed. |
Resources deployed
The template deploys the following resources in your environment:
Resource | Description |
---|---|
Managed identity | The name of the managed identity is of the format mi_UniqueValue. This managed identity is assigned to the logic app, and is granted access to the storage account, FHIR server, and the Dataverse environment. |
Azure storage account | The name of the storage account is of the format sa_UniqueValue. Along with the storage account, the template also deploys the following three containers - bundles , bundlesarchive , and bundleserror . |
Role assignment | Assigns the Storage Blob Data Contributor role on the storage account to the managed identity. |
Azure Event Grid | The name of the Event Grid is of the format eg_UniqueValue. All the blob events are posted to this Event Grid. |
Azure Service Bus | The name of the Service Bus is of the format sb_UniqueValue. The Event Grid posts events to this Service Bus. The name of the queue is bundleCreated . |
Authorization rule | Creates a Listen authorization rule on the Service Bus with the name bundleauthlisten . |
Azure Logic Apps | A set of related logic app workflow of the type Consumption. The workflow triggers off the Service Bus events. These logic apps process the incoming FHIR bundle and post it to the configured endpoints. Each logic app is named using the unique value provided during deployment: 1. laprocessfhirbundle_UniqueValue 2. lasendbundletodataverse_UniqueValue 3. lasendbundletofhir_UniqueValue |
API Connection | Several API connections required for the logic apps. |
Output
Based on whether the run terminates with a success or an error, a blob with the name originalblobname_response.json is created in the bundlesarchive
or bundleserror
folder with the following schema:
{
"dataverseResponse": "<The response from the Dataverse healthcare API post the call.>",
"fhirServerResponse": "<The response from the FHIR server call if the "Post to FHIR server" parameter value was set to True.>",
"statusMessage": "<Summary of the responses. In case of a failure, the message provides details about how many resources failed to post to the FHIR server and to Dataverse.>",
"statusCode": "<Code value associated with the issue encountered.>"
}
Depending on which logic app triggered the error, the JSON error contains either the dataverseResponse
or fhirServerResponse
node. For example, if you encounter an error with the lasendbundletofhir_UniqueValue logic app, the JSON response only contains the fhirServerResponse
node and value.
Post deployment steps
The following section contains the steps that you need to follow after deploying the template.
Grant access to the FHIR server
Accessing the FHIR server from the logic app requires the FHIR Data Contributor role assignment, which allows posting new data to the service. Add this Azure role assignment to the managed identity used by the logic app.
Go to the FHIR server instance, select Access Control (IAM), and then select Add role assignment.
In the Role tab, select the FHIR Data Contributor role.
Select Members, select Managed identity, and then select + Select members.
Add the managed identity created with the ARM template deployment. The newly deployed managed identity should be named mi_UniqueValue.
The assignment might take a few minutes to reflect on the managed identity. Select Azure role assignments to view the role assignment on the managed identity.
Grant access to Dataverse healthcare APIs
The same managed identity is used in the logic app to access the Dataverse healthcare APIs by connecting it to an application user in the target Dataverse instance. For more information about application users, go to Manage application users in the Power Platform admin center.
You need the Azure Client ID for the managed identity to configure the application user. To retrieve the Client ID, open the managed identity created with the ARM template deployment and copy the Client ID value from the Overview area.
In the Power Platform admin center, open the target Microsoft Cloud for Healthcare environment. In the Access section, select S2S Apps, and then select New app user.
In the Create a new app user pane, select the appropriate Business unit, and then select Add an app.
In the Add an app from Microsoft Entra ID pane, search for the Client ID you copied from the managed identity.
Select the managed identity from the list, select Add, and then edit the security roles.
Select the Sync admin for FHIR App Reg User role, and then select Save.
Select Create to create the new application user.
After you complete the configuration, you can test the logic app workflow by posting a sample bundle to the sa_UniqueValue container for processing. Depending on your solution requirement, you can also modify any of these logic apps for more processing.
Handle errors
If a logic app run results in an error, a file with the name originalblobname_response.json is created in the bundleserror
container in the storage account. You can parse through this file to identify the root cause of the error, fix it, and resubmit the bundle with the failed resources.
Bundle type: Batch
The FHIR server and the Dataverse healthcare APIs process a bundle of the type batch as a group of independent actions. As a result, the responses indicate the success and failure of each resource independently.
As per the FHIR specification, any resource that fails results in an OperationOutcome with severity value set to error, while the Dataverse healthcare API sets the msind_requeststatus
to 935000002. For more information about the request status types, go to Types of request status.
The logic app workflow parses through both the responses from the FHIR server and the Dataverse healthcare APIs. It terminates the flow as Failed if there's any resource that resulted in an error.
Note
Dataverse healthcare APIs currently only support FHIR bundles of the type batch and batch-response.
Set up retries
After you identify and fix the error, you can place the bundle back in the bundles
container for reprocessing.
Retry on throttle: FHIR server
The HTTP action in the logic app workflow that posts to the FHIR server uses the built-in HTTP action retry policies. The default value is an exponential interval policy set to retry four times. You can edit the retry policy.
Select the ellipsis in the upper-right corner of the action card, and then select Settings.
Under Retry Policy, change the value of the field Type.
Retry on throttle: Dataverse healthcare APIs
The Service protection API limits affect the Dataverse healthcare APIs. If a request to Dataverse healthcare APIs gets throttled, the logic app workflow retries three times (by default) at the Retry-After
interval specified by the API in the response header. You can edit both the retry count and the interval.
To change the retry count, edit the Count value in the Loop until action.
To change the interval, edit the Count value in the Delay action.
Secure Logic Apps
After you finish setting up and testing the logic app, you can lock down the tracing by securing the inputs and outputs actions. To learn more, go to Secure Logic App.