This repository was archived by the owner on Mar 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 75
Added IoMT Scenario and IaC Pattern #1
Closed
Closed
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
7aabc3a
Added Healthcare API Template
marvinbuss f23265d
Added Healthcare API Policy for Diags
marvinbuss 88b6876
adding sample parameter file
marvinbuss 52dac60
added readme for solution
marvinbuss 057740a
updated readme
marvinbuss 783add6
updated docs
marvinbuss 120eb61
Merge branch 'main' into healthcare_api
marvinbuss 10ae33f
linting
marvinbuss 772f16c
Merge branch 'main' of https://github.com/microsoft/industry into hea…
marvinbuss f4693be
* merged main
marvinbuss a0f9c96
* added container registry
marvinbuss 9a03229
Merge branch 'main' into healthcare_api
marvinbuss 79d00ec
moving from account to file system role assignment
marvinbuss 573d823
added portal ui for deployment
marvinbuss b96726a
Merge branch 'main' into healthcare_api
marvinbuss 18e552f
Merge branch 'main' into healthcare_api
marvinbuss eb59ef4
Merge branch 'main' into healthcare_api
marvinbuss bfb553c
updated name of resource
marvinbuss 3a0951e
Merge branch 'healthcare_api' of https://github.com/microsoft/industr…
marvinbuss 710bfbe
Merge branch 'main' into healthcare_api
marvinbuss eb7035b
* Added IoT Hub
marvinbuss f4d9c33
added max value
marvinbuss 34e001e
* updated Readme
marvinbuss e891b72
Updated Readme
marvinbuss fd1bec5
Updated readme and scenario deployment
marvinbuss 56c53d7
Further updated in d365 section and fix typos
marvinbuss c94dd81
linting
marvinbuss f555c77
removed section
marvinbuss f73b8aa
Added Service Bus namespace and queue
marvinbuss 476bad0
Added comment about outputs
marvinbuss ec1114c
bug fixes
marvinbuss 7f9a420
remove references
marvinbuss 6bdd113
updated readme
marvinbuss a5d1b00
Added reference to Azure function
marvinbuss c8dd333
updated portal ui def
marvinbuss 1b08408
update deploy to msft button
marvinbuss fa667a6
Added architecture and smaller updates to readme
marvinbuss f7314c1
Updated URI for deploy to MSFT button
marvinbuss aa45300
Merge branch 'main' of https://github.com/microsoft/industry into hea…
marvinbuss e92b254
Merge branch 'main' of https://github.com/microsoft/industry into hea…
marvinbuss 37fd0c4
Added interface descriptions to diagram
marvinbuss 1f576a8
moved policy definitions and updated docs
marvinbuss b433585
Merge branch 'main' of https://github.com/microsoft/industry into hea…
marvinbuss 27ce9c2
first st of updates
marvinbuss 4b302a9
updated default parameter and portal UI
marvinbuss 70974b9
merge
marvinbuss 85366f4
updated readme
marvinbuss 1d196b2
update files
marvinbuss File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
...mplementation/industrySpecific/Policies/PolicyDefinitions/deploy.policyDefinition.mg.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| { | ||
| "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "policyName": { | ||
| "type": "string", | ||
| "metadata": { | ||
| "description": "Specifies the name of the policy." | ||
| } | ||
| }, | ||
| "policyDescription": { | ||
| "type": "string", | ||
| "metadata": { | ||
| "description": "Specifies a description of the policy." | ||
| } | ||
| }, | ||
| "policyMode": { | ||
| "type": "string", | ||
| "defaultValue": "All", | ||
| "allowedValues": [ | ||
| "All", | ||
| "Indexed", | ||
| "Microsoft.KeyVault.Data", | ||
| "Microsoft.Kubernetes.Data" | ||
| ], | ||
| "metadata": { | ||
| "description": "Specifies the mode of the policy set." | ||
| } | ||
| }, | ||
| "policyParameters": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies the parameters of the policy." | ||
| } | ||
| }, | ||
| "policyDefinition": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies the Policy itself." | ||
| } | ||
| }, | ||
| "policyMetadata": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies key-value pairs for the policy." | ||
| } | ||
| } | ||
| }, | ||
| "variables": { | ||
| "policyName": "[parameters('policyName')]", | ||
| "policyDescription": "[parameters('policyDescription')]", | ||
| "policyParameters": "[parameters('policyParameters')]", | ||
| "policyDefinition": "[parameters('policyDefinition')]", | ||
| "policyMode": "[parameters('policyMode')]", | ||
| "policyMetadata": "[parameters('policyMetadata')]" | ||
| }, | ||
| "resources": [ | ||
| { | ||
| "type": "Microsoft.Authorization/policyDefinitions", | ||
| "apiVersion": "2020-03-01", | ||
| "name": "[variables('policyName')]", | ||
| "properties": { | ||
| "policyType": "Custom", | ||
| "mode": "[variables('policyMode')]", | ||
| "displayName": "[variables('policyName')]", | ||
| "description": "[variables('policyDescription')]", | ||
| "parameters": "[variables('policyParameters')]", | ||
| "policyRule": "[variables('policyDefinition')]", | ||
| "metadata": "[variables('policyMetadata')]" | ||
| } | ||
| } | ||
| ] | ||
| } |
73 changes: 73 additions & 0 deletions
73
...plementation/industrySpecific/Policies/PolicyDefinitions/deploy.policyDefinition.sub.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| { | ||
| "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "policyName": { | ||
| "type": "string", | ||
| "metadata": { | ||
| "description": "Specifies the name of the policy." | ||
| } | ||
| }, | ||
| "policyDescription": { | ||
| "type": "string", | ||
| "metadata": { | ||
| "description": "Specifies a description of the policy." | ||
| } | ||
| }, | ||
| "policyMode": { | ||
| "type": "string", | ||
| "defaultValue": "All", | ||
| "allowedValues": [ | ||
| "All", | ||
| "Indexed", | ||
| "Microsoft.KeyVault.Data", | ||
| "Microsoft.Kubernetes.Data" | ||
| ], | ||
| "metadata": { | ||
| "description": "Specifies the mode of the policy set." | ||
| } | ||
| }, | ||
| "policyParameters": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies the parameters of the policy." | ||
| } | ||
| }, | ||
| "policyDefinition": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies the Policy itself." | ||
| } | ||
| }, | ||
| "policyMetadata": { | ||
| "type": "object", | ||
| "metadata": { | ||
| "description": "Specifies key-value pairs for the policy." | ||
| } | ||
| } | ||
| }, | ||
| "variables": { | ||
| "policyName": "[parameters('policyName')]", | ||
| "policyDescription": "[parameters('policyDescription')]", | ||
| "policyParameters": "[parameters('policyParameters')]", | ||
| "policyDefinition": "[parameters('policyDefinition')]", | ||
| "policyMode": "[parameters('policyMode')]", | ||
| "policyMetadata": "[parameters('policyMetadata')]" | ||
| }, | ||
| "resources": [ | ||
| { | ||
| "type": "Microsoft.Authorization/policyDefinitions", | ||
| "apiVersion": "2020-03-01", | ||
| "name": "[variables('policyName')]", | ||
| "properties": { | ||
| "policyType": "Custom", | ||
| "mode": "[variables('policyMode')]", | ||
| "displayName": "[variables('policyName')]", | ||
| "description": "[variables('policyDescription')]", | ||
| "parameters": "[variables('policyParameters')]", | ||
| "policyRule": "[variables('policyDefinition')]", | ||
| "metadata": "[variables('policyMetadata')]" | ||
| } | ||
| } | ||
| ] | ||
| } |
134 changes: 134 additions & 0 deletions
134
...industrySpecific/Policies/PolicyDefinitions/healthCareApis/params.diagnosticSettings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| { | ||
| "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "policyName": { | ||
| "value": "DiagnosticSettings-HealthcareApisFhir-LogAnalytics" | ||
| }, | ||
| "policyDescription": { | ||
| "value": "Send diagnostic settings for azure healthcare api fhir to log analytics workspace." | ||
| }, | ||
| "policyMode": { | ||
| "value": "Indexed" | ||
| }, | ||
| "policyParameters": { | ||
| "value": { | ||
| "effect": { | ||
| "type": "String", | ||
| "metadata": { | ||
| "displayName": "Effect", | ||
| "description": "Enable or disable the execution of the policy" | ||
| }, | ||
| "allowedValues": [ | ||
| "DeployIfNotExists", | ||
| "Disabled" | ||
| ], | ||
| "defaultValue": "DeployIfNotExists" | ||
| }, | ||
| "logAnalytics": { | ||
| "type": "string", | ||
| "metadata": { | ||
| "displayName": "Log Analytics workspace", | ||
| "description": "Select the Log Analytics workspace from the dropdown list", | ||
| "strongType": "omsWorkspace" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "policyDefinition": { | ||
| "value": { | ||
| "if": { | ||
| "field": "type", | ||
| "equals": "Microsoft.HealthcareApis/workspaces/fhirservices" | ||
| }, | ||
| "then": { | ||
| "effect": "[parameters('effect')]", | ||
| "details": { | ||
| "type": "Microsoft.Insights/diagnosticSettings", | ||
| "name": "setByPolicy", | ||
| "existenceCondition": { | ||
| "allOf": [ | ||
| { | ||
| "field": "Microsoft.Insights/diagnosticSettings/logs.enabled", | ||
| "equals": "true" | ||
| }, | ||
| { | ||
| "field": "Microsoft.Insights/diagnosticSettings/metrics.enabled", | ||
| "equals": "true" | ||
| }, | ||
| { | ||
| "field": "Microsoft.Insights/diagnosticSettings/workspaceId", | ||
| "equals": "[parameters('logAnalytics')]" | ||
| } | ||
| ] | ||
| }, | ||
| "roleDefinitionIds": [ | ||
| "/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa", | ||
| "/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293" | ||
| ], | ||
| "deployment": { | ||
| "properties": { | ||
| "mode": "incremental", | ||
| "template": { | ||
| "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "resourceName": { | ||
| "type": "string" | ||
| }, | ||
| "logAnalytics": { | ||
| "type": "string" | ||
| }, | ||
| "location": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "variables": {}, | ||
| "resources": [ | ||
| { | ||
| "type": "Microsoft.HealthcareApis/workspaces/fhirservices/providers/diagnosticSettings", | ||
| "apiVersion": "2017-05-01-preview", | ||
| "name": "[concat(parameters('resourceName'), '/', 'Microsoft.Insights/setByPolicy')]", | ||
| "location": "[parameters('location')]", | ||
| "dependsOn": [], | ||
| "properties": { | ||
| "workspaceId": "[parameters('logAnalytics')]", | ||
| "metrics": [], | ||
| "logs": [ | ||
| { | ||
| "category": "AuditLogs", | ||
| "enabled": true | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ], | ||
| "outputs": {} | ||
| }, | ||
| "parameters": { | ||
| "logAnalytics": { | ||
| "value": "[parameters('logAnalytics')]" | ||
| }, | ||
| "location": { | ||
| "value": "[field('location')]" | ||
| }, | ||
| "resourceName": { | ||
| "value": "[field('name')]" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "policyMetadata": { | ||
| "value": { | ||
| "version": "1.0.0", | ||
| "category": "Cognitive Services", | ||
| "preview": false, | ||
| "deprecated": false | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Internet of Medical Things | ||
|
|
||
| Internet of Medical Things (IoMT) is a subcategory of Internet of Things (IoT) and focusses on the practical application of IoT in the area of healthcare. In IoMT scenarios medical data is collected and sometime pre-processed through the means of internet-connected medical devices and then sent to a datacenter in (near) real-time. The data can then be used for various data-driven applications and use-cases including: | ||
|
|
||
| - The prediction of medical states and incidents for device users as well as healthcare providers. | ||
| - Allowing healthcare professional to remotely monitor patients' key biometrics in (near) real-time. | ||
| - Shorter time to diagnosis, because of more efficient and quick data exchange, asynchronous analysis of datasets and analysis of mdeical data, before impactful medical incidents take place. No in-person visits required. | ||
|
|
||
| Classical IoT as well as IoMT scenarios share similar architectures. The most significant differences can be identified on the application and data-driven use-case level. Also, there is a higher emphasis on the security aspect in the IoMT space and the compliance with legal regulations and standards. In the next paragraphs, we will look at the various layers of an IoMT architecture. | ||
|
|
||
| ## IoMT Architecture | ||
|
|
||
| The architecture diagram depicts a typical IoMT scenario, where internet-connected devices collect protected health information (PHI) of patients and then transmit the data points over one or multiple gateways to the cloud. | ||
|
|
||
|  | ||
|
|
||
| After the data has reached the Azure datacenter, data can be further processed by using tools such as Azure Functions, Azure Synapse or Azure Stream Analytics. Finally, data usually gets persisted onto one of the various data services inside Azure like Azure Cosmos DB, Azure Storage, Azure Synapse SQL Pool or Azure Healthcare APIs. | ||
|
|
||
| Except for the data persistence layer, the Microsoft Cloud for Healthcare does not offer any industry-specific solutions for realizing such end-to-end scenarios. Today, standard Azure services including Azure IoT Edge, Azure IoT Hub or Azure Synapse must be used by customers to realize such architectures. Only for the storage layer, the industry-specific Azure Healthcare APIs service is available, which supports standards such as Fast Healthcare Interoperability Resources (FHIR), Digital Imaging and Communications in Medicine (DICOM) and conversion of multiple other data standards into FHIR. | ||
|
|
||
| Due to sensitivity of the data being transmitted, security is a key factor and various kinds of regulations have to be fulfilled by companies when realizing IoMT scenarios. However, a key factor of success of such solutions depends on the use of Machine Learning and integrated Dashboards, as the sheer size of data makes it impossible to review all datapoints. | ||
|
|
||
| ## Dynamics 365 Integration | ||
|
|
||
| Within Dynamics 365, the Microsoft Cloud for Healthcare offers a comprehensive set of solutions for the healthcare market to expedite a healthcare organization’s ability to roll out solutions. Patients, providers, and care coordinators can perform daily duties in a modern yet familiar user-interface that provides robust functionality. An overview of the ever-growing list of Dynamics 365 healthcare solutions can be found [here](https://docs.microsoft.com/en-us/dynamics365/industry/healthcare/overview). | ||
|
|
||
| The healtcare data model for Dynamics 365 is also based on the FHIR framework, which makes it easier for customers and partners to develop new applications without redefining the healthcare data architecture. | ||
|
|
||
| In order to not end up with two disparate systems and datasets, customers can make use of a FHIR synch agent to synch datapoints and updates between Dataverse and Azure Healthcare APIs. The synch Agent consists of two components, the FHIR Synch Agent service and the FHIR Synch Agent Administration Application. Both components are required to synch data between Azure and the Power Platform. The synch must be setup by providing few application secrets as well as Service Bus Queue propertied. | ||
|
|
||
| Within the FHIR Synch Agent Administration Application, administrators can define entity maps, attribute maps and expansion maps. Sync Agent Logs can be used to validate synch operations and to understand why a certain datapoint is sent over the services bus and why others are not. | ||
|
|
||
| This allows customers to leverage datasets, collected in IoMT sceanrios, in Dynamics 365 to further enhance the patients experience and quality of results. Additional applications and data-driven solutions can be built to simplify the end-to-end experience for all participants and reduce the time to diagnosis. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| The Infrastructure as Code (IaC) templates in this solution folder can be used for the implementation of IoMT scenarios as well as the Dynamics 365 synch described above. The solution will deploy the following resources into a single resource group (resource-group level deployment): | ||
|
|
||
| - [Azure Healthcare APIs](https://docs.microsoft.com/en-us/azure/healthcare-apis/healthcare-apis-overview) | ||
| - [Azure Health Bot (optional)](https://docs.microsoft.com/en-us/azure/health-bot/) | ||
| - [Azure Event Hub (optional)](https://docs.microsoft.com/azure/event-hubs/) or | ||
| - [Azure IoT Hub (optional)](https://docs.microsoft.com/azure/iot-hub/about-iot-hub) | ||
| - [Azure Container Registry](https://docs.microsoft.com/en-us/azure/container-registry/) | ||
| - [Azure Service Bus](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview) | ||
| - [Azure Function](https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview) | ||
|
|
||
| Please use the following "Deploy to Azure" button to get started with this accelerator: | ||
|
marvinbuss marked this conversation as resolved.
|
||
|
|
||
| [](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Findustry%2Fmain%2FHealthcare%2Fsolutions%2FIoMT%2Fmain.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Findustry%2Fmain%2FHealthcare%2Fsolutions%2FIoMT%2Fportal.json) | ||
|
|
||
| The deployment outputs will provide the details required to setup the synch between Azure Healthcare APIs and Dataverse in Dynamics 365 via the FHIR Synch Agent. | ||
|
|
||
| ### Policies | ||
|
marvinbuss marked this conversation as resolved.
|
||
|
|
||
| Custom Policies for the industry specific services used in this solution can be found in the folder [`/healthcare/referenceImplementation/industrySpecific/Policies/PolicyDefinitions/healthCareApis`](/healthcare/referenceImplementation/industrySpecific/Policies/PolicyDefinitions/healthCareApis). These policies can be deployed using: | ||
|
|
||
| 1. [ARM template for deployment to subscription scope](/healthcare/referenceImplementation/industrySpecific/Policies/PolicyDefinitions/deploy.policyDefinition.sub.json) | ||
| 2. [ARM template for deployment to management group scope](/healthcare/referenceImplementation/industrySpecific/Policies/PolicyDefinitions/deploy.policyDefinition.mg.json) | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great. I was also wondering (although knowing it's early stage) if we can lead with critical design areas for IoMT, and flush out some design considerations/recommendations across those? That should help to position the reference architecture and the rationale behind the composition and integration we are recommending. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I work on this as part of a second iteration?
Would that work?