Skip to content

Commit

Permalink
Personal/sgupta/smartonfhir (#141)
Browse files Browse the repository at this point in the history
* Commit as per US 109931

* Commit as per US 109931

* Commit as per US 109931

* Commit

* Coomit as per US 109931

* Added Fhir resource group fetch from Id

* Adding fhirid parameter in fhir.bicep file

* Commit for parameter

* COMMIT

* Commit when fhirid is empty

* Removing extra parameters

* Update main.bicep

* Commit for US 109931

* Commit as per US 109931

* Removed two parameter

* Updated Document to provide details about using existing fhir server instance as a parameter

* User v-gkuber - reverting changes done for setting manifest json file

---------

Co-authored-by: Shreshtha Gupta <[email protected]>
Co-authored-by: Shashank Narang <[email protected]>
  • Loading branch information
3 people authored Oct 18, 2023
1 parent d38369d commit 4c8944f
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 67 deletions.
25 changes: 14 additions & 11 deletions samples/smartonfhir/docs/ad-apps/fhir-resource-app-registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ This application registration is used to customize the access token sent to the

## Deployment (manual)

1. Find your Primary Domain in Azure Active Directory
- Open Azure AD in the Azure Portal
- Note your `Primary Domain` in the Overview blade of Azure AD.
1. Create a FHIR Resource Application Registration
- Go to `App Registrations`
- Create a new application. It's easiest if this matches the name of your Azure Developer CLI environment.
- Click `Register` (ignore redirect URI).
1. Set the application URL
- Go to `Expose an API` blade.
- Set the application URL to https://<app-registration-name>.<Azure AD Primary Domain>.
- For example `https://my-app-1.mytenant.onmicrosoft.com`.
- Save the `Application URL` for later.
1. Add all the applicable FHIR Scopes.
- Go to the Manifest blade for your application.
- Change `acceptMappedClaims` from null to true.
- Copy the `appRoles` JSON element from [fhir-app-manifest.json](./fhir-app-manifest.json) to the `appRoles` JSON element in your application manifest.
- Copy the `oauth2Permissions` JSON element from [fhir-app-manifest.json](./fhir-app-manifest.json) to the `oauth2Permissions` JSON element in your application manifest.
1. Inform your Azure Developer CLI environment of this application with:
```
azd env set FhirAudience <FHIR Resource Application ID URI>
azd env set FhirResourceAppId <FHIR Resource App Id>
```
1. Run below command to configure a FHIR Resource Application Registration.
Windows:
```powershell
powershell ./scripts/Configure-FhirResourceAppRegistration.ps1
```
Mac/Linux
```bash
pwsh ./scripts/Configure-FhirResourceAppRegistration.ps1
```
1. Create a Microsoft Graph Directory Extension to hold the `fhirUser` information for users.
Windows:
Expand Down
6 changes: 5 additions & 1 deletion samples/smartonfhir/docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ Next you will need to clone this repository and prepare your environment for dep
azd env set ApiPublisherEmail "Your Email"
```
1. Finally, deploy your environment by running azd. This command will provision infrastructure and deploy code. It will take about an hour.
- You will need to provide `subscription name` and `location` during exection of this command where all the required resource will get deployed.
- During the execution of this command, you will need to select `subscription name` and `location` from the drop down to specify where all resources will get deployed.
- To create a new resource group for SMART on FHIR resources deployment, leave the `existingResourceGroupName` parameter blank; otherwise, enter the name of an existing resource group where you want to deploy all of your SMART on FHIR resources.
- If you want to create a new FHIR server instance, leave the `fhirid` parameter blank. Otherwise, provide the FHIR instance id of existing FHIR server instance in case you want to use existing FHIR server instance.
- To get the FHIR instance Id go to your fhir service and in left menu click on properties and Copy the Id field.
- Multiple SMART on FHIR apps can not be deployed in same resource group and it's expected to have FHIR server instance and SMART on FHIR resources deployed in same resource group.
- You can continue the setup below.
```
azd up
Expand Down
3 changes: 3 additions & 0 deletions samples/smartonfhir/infra/core/fhir.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ param tenantId string
param location string
param audience string = ''
param appTags object = {}
param fhirInstanceResourceGroup string

var loginURL = environment().authentication.loginEndpoint
var authority = '${loginURL}${tenantId}'
Expand All @@ -19,6 +20,7 @@ resource healthWorkspace 'Microsoft.HealthcareApis/workspaces@2021-06-01-preview

resource healthWorkspaceExisting 'Microsoft.HealthcareApis/workspaces@2021-06-01-preview' existing = if (!createWorkspace) {
name: workspaceName
scope: resourceGroup(fhirInstanceResourceGroup)
}
var newOrExistingWorkspaceName = createWorkspace ? healthWorkspace.name : healthWorkspaceExisting.name

Expand All @@ -44,6 +46,7 @@ resource fhir 'Microsoft.HealthcareApis/workspaces/fhirservices@2021-06-01-previ

resource fhirExisting 'Microsoft.HealthcareApis/workspaces/fhirservices@2021-06-01-preview' existing = if (!createFhirService) {
name: '${newOrExistingWorkspaceName}/${fhirServiceName}'
scope: resourceGroup(fhirInstanceResourceGroup)
}

output fhirId string = createFhirService ? fhir.id : fhirExisting.id
Expand Down
60 changes: 32 additions & 28 deletions samples/smartonfhir/infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,15 @@ param FhirAudience string

// start optional configuration parameters

@description('Do you want to create a new Azure Health Data Services workspace or use an existing one?')
param createWorkspace bool = true

@description('Do you want to create a new FHIR Service or use an existing one?')
param createFhirService bool = true

@description('Name of Azure Health Data Services workspace to deploy or use. Leave blank for default.')
param workspaceName string = ''

@description('Name of the FHIR service to deloy or use. Leave blank for default.')
param fhirServiceName string = ''
@description('Name of your existing resource group (leave blank to create a new one)')
param existingResourceGroupName string

@description('Name of the Log Analytics workspace to deploy or use. Leave blank to skip deployment')
param logAnalyticsName string = ''

@description('Id of the FHIR Service to load resources into. (Get it from your fhir service properties)')
param fhirid string

// end optional configuration parameters

var nameClean = replace(name, '-', '')
Expand All @@ -66,24 +60,35 @@ var tenantId = subscription().tenantId
// Add any extra principals that need to be able to access the Key Vault
var fhirSMARTPrincipals = []
var fhirContributorPrincipals = [ principalId ]

var createResourceGroup = empty(existingResourceGroupName) ? true : false
var createWorkspace = empty(fhirid) ? true : false
var createFhirService = empty(fhirid) ? true : false

@description('Resource group to deploy sample in.')
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = if (createResourceGroup) {
name: '${name}-rg'
location: location
tags: appTags
}

var workspaceNameResolved = length(workspaceName) > 0 ? workspaceName : '${replace(nameCleanShort, '-', '')}health'
var fhirNameResolved = length(fhirServiceName) > 0 ? workspaceName : 'fhirdata'
resource existingResourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' existing = if (!createResourceGroup) {
name: existingResourceGroupName
}

var fhirUrl = 'https://${workspaceNameResolved}-${fhirNameResolved}.fhir.azurehealthcareapis.com'
var newOrExistingResourceGroupName = createResourceGroup ? rg.name : existingResourceGroup.name
var fhirResourceIdSplit = split(fhirid,'/')
var fhirserviceRg = empty(fhirid) ? '' : fhirResourceIdSplit[4]
var workspaceNameResolved = empty(fhirid) ? '${replace(nameCleanShort, '-', '')}health' : fhirResourceIdSplit[8]
var fhirNameResolved = empty(fhirid) ? 'fhirdata' : fhirResourceIdSplit[10]
var fhirInstanceResourceGroup = empty(fhirid) ? newOrExistingResourceGroupName : fhirserviceRg

@description('Deploy Azure Health Data Services and FHIR service')
module fhir 'core/fhir.bicep'= {
name: 'azure-health-data-services'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
fhirInstanceResourceGroup: fhirInstanceResourceGroup
createWorkspace: createWorkspace
createFhirService: createFhirService
workspaceName: workspaceNameResolved
Expand All @@ -103,7 +108,7 @@ var logAnalyticsNameResolved = length(logAnalyticsName) > 0 ? logAnalyticsName :
@description('Deploy monitoring and logging')
module monitoring 'core/monitoring.bicep'= {
name: 'monitoringDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
logAnalyticsName: logAnalyticsNameResolved
appInsightsName: appInsightsName
Expand All @@ -115,7 +120,7 @@ module monitoring 'core/monitoring.bicep'= {
@description('Deploy base resources needed for function app based custoom operations.')
module functionBase 'core/functionHost.bicep' = {
name: 'functionBaseDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
appTags: appTags
location: location
Expand All @@ -127,7 +132,7 @@ module functionBase 'core/functionHost.bicep' = {
@description('Deploy Redis Cache for use as External Cache for APIM')
module redis './core/redisCache.bicep'= {
name: 'redisCacheDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
apiManagementServiceName: apimName
location: location
Expand All @@ -137,7 +142,7 @@ module redis './core/redisCache.bicep'= {
@description('Azure Health Data Services Toolkit auth custom operation function app')
module authCustomOperation './app/authCustomOperation.bicep' = {
name: 'authCustomOperationDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
name: name
location: location
Expand All @@ -158,9 +163,9 @@ module authCustomOperation './app/authCustomOperation.bicep' = {
}

@description('Setup identity connection between FHIR and the given contributors')
module fhirContributorIdentities './core/identity.bicep' = [for principalId in fhirContributorPrincipals: {
module fhirContributorIdentities './core/identity.bicep' = [for principalId in fhirContributorPrincipals: if(createResourceGroup && empty(fhirid)) {
name: 'fhirIdentity-${principalId}-fhirContrib'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
fhirId: fhir.outputs.fhirId
principalId: principalId
Expand All @@ -172,7 +177,7 @@ module fhirContributorIdentities './core/identity.bicep' = [for principalId in
@description('Setup identity connection between FHIR and the given SMART users')
module fhirSMARTIdentities './core/identity.bicep' = [for principalId in fhirSMARTPrincipals: {
name: 'fhirIdentity-${principalId}-fhirSmart'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
fhirId: fhir.outputs.fhirId
principalId: principalId
Expand All @@ -186,7 +191,7 @@ var apimName = '${name}-apim'
@description('Deploy Azure API Management for the FHIR gateway')
module apim './core/apiManagement.bicep'= {
name: 'apiManagementDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
apiManagementServiceName: apimName
publisherEmail: ApiPublisherEmail
Expand All @@ -202,7 +207,7 @@ module apim './core/apiManagement.bicep'= {
@description('Link Redis Cache to APIM')
module redisApimLink './core/apiManagement/redisExternalCache.bicep'= {
name: 'apimRedisLinkDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
apiManagementServiceName: apimName
redisApiVersion: redis.outputs.redisApiVersion
Expand All @@ -215,7 +220,7 @@ var authorizeStaticWebAppName = '${name}-contextswa'
@description('Static web app for SMART Context UI')
module contextStaticWebApp './app/contextApp.bicep' = {
name: 'staticWebAppDeploy'
scope: rg
scope: resourceGroup(newOrExistingResourceGroupName)
params: {
staticWebAppName: authorizeStaticWebAppName
location: location
Expand All @@ -234,10 +239,9 @@ output ExportStorageAccountUrl string = 'https://${functionBase.outputs.storageA
output ApiManagementHostName string = apim.outputs.apimHostName
output ContextAppClientId string = ContextAppClientId
output CacheConnectionString string = authCustomOperation.outputs.cacheConnectionString

output AzureAuthCustomOperationManagedIdentityId string = authCustomOperation.outputs.functionAppPrincipalId

output REACT_APP_AAD_APP_CLIENT_ID string = ContextAppClientId
output REACT_APP_AAD_APP_TENANT_ID string = tenantId
output REACT_APP_API_BASE_URL string = 'https://${apim.outputs.apimHostName}'
output REACT_APP_FHIR_RESOURCE_AUDIENCE string = FhirAudience
output AZURE_RESOURCE_GROUP string = newOrExistingResourceGroupName
54 changes: 30 additions & 24 deletions samples/smartonfhir/infra/main.parameters.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"value": "${AZURE_ENV_NAME}"
},
"location": {
"value": "${AZURE_LOCATION}"
},
"principalId": {
"value": "${AZURE_PRINCIPAL_ID}"
},
"ApiPublisherName": {
"value": "${ApiPublisherName=Placeholder Name}"
},
"ApiPublisherEmail": {
"value": "${[email protected]}"
},
"FhirAudience": {
"value": "${FhirAudience}"
},
"ContextAppClientId": {
"value": "${ContextAppClientId}"
}
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ApiPublisherEmail": {
"value": "${[email protected]}"
},
"ApiPublisherName": {
"value": "${ApiPublisherName=Placeholder Name}"
},
"ContextAppClientId": {
"value": "${ContextAppClientId}"
},
"existingresourcegroupname": {
"value": ""
},
"FhirAudience": {
"value": "${FhirAudience}"
},
"fhirId": {
"value": ""
},
"location": {
"value": "${AZURE_LOCATION}"
},
"name": {
"value": "${AZURE_ENV_NAME}"
},
"principalId": {
"value": "${AZURE_PRINCIPAL_ID}"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"displayName": "user.all.all",
"id": "5a03b38d-4081-4265-9558-aab5f2b18b8b",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "user.all.all"
},
Expand All @@ -19,7 +18,6 @@
"displayName": "user.all.read",
"id": "5a03b38d-4081-4265-9558-aab5f2a18b8b",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "user.all.read"
},
Expand All @@ -31,7 +29,6 @@
"displayName": "system.all.read",
"id": "446c1a33-8f34-43b3-855c-db21aab2889f",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "system.all.read"
}
Expand Down

0 comments on commit 4c8944f

Please sign in to comment.