FHIR Server in Azure (PaaS)

Fast Healthcare Interoperability Resources (FHIR) is a draft standard describing data formats and elements (known as "resources") and an application programming interface (API) for exchanging electronic health records. There are a number of implementations of libraries and servers already out there. In this blog post, I will show you how to run a FHIR server in Azure using PaaS services. Specifically, I will demonstrate how to run the frontend of a FHIR server in an Azure Web App and the backend using either Azure SQL Database or Azure Cosmos DB. You can find the templates and instructions in my https://github.com/hansenms/fhir-azure repository on GitHub.

There is a FHIR .NET API implementation. Based on that library, the company Firely has implemented few different FHIR servers. They have an open source Spark server, which implements Draft Standard for Trial Use 2 (DSTU2) and a commercial Vonk server, which implements Standard for Trial Use 3 (STU3). I have created templates that will allow easy deployment of:

  1. Firely Spark with Cosmos DB (MongoDb API) backend.
  2. Firely Vonk with Cosmos DB (MongoDb API) backend.
  3. Firely Vonk with Azure SQL Database as backend.

The first two of these configurations are not officially mentioned as supported by any of the documentation and they should be considered for experimentation only. The third option (Vonk with SQL backend) could be considered for production deployments. Vonk is a commercial product and a license is needed. I have used a trial license for Vonk.

Deploying Firely Spark

The template for Firely Spark deploys a Web App and a Cosmos DB backend. It then sets all the appropriate app settings (including connection strings) on the web app and pulls the code for the server from a GitHub repository. It actually pulls the code from my dastu2/azure branch of the source code repository. I had to make a few code changes to make it work with Cosmos DB and in an Azure Web App. The key change was to force the MongoDb client to use TLS1.2 (in MongoDatabaseFactory.cs):

[ps]
private static MongoDatabase CreateMongoDatabase(string url)
{
var mongourl = new MongoUrl(url);

//Switch to Tls12 only to be compatible with CosmosDB
var settings = MongoClientSettings.FromUrl(mongourl);
settings.SslSettings = new SslSettings();
settings.SslSettings.EnabledSslProtocols = SslProtocols.Tls12;
var client = new MongoClient(settings);

return client.GetServer().GetDatabase(mongourl.DatabaseName);
}
[/ps]

In addition to this I also switched off direct file system logging, which was causing some problems in a Web App. These are really just some hacks to make it run and some more thorough testing would probably identify additional issues. This is not production code.

On the page with template for Firely Spark you should find buttons for deploying to Azure Commercial or Azure Government. It should deploy in 5 minutes or so. You may find that the deployment initially fails to deploy the code. It is a large code repository and it may time out during the build. If that happens, simply go to the deployment options for the Web App and redeploy. Once the code is deployed, hit the website and you should see the Spark FHIR server front page:

If you visit the https://FHIR-SERVER-URL/maintenance/initialize endpoint for the server, you should be able to populate it with some test data and then subsequently do a GET https://FHIR-SERVER-URL/fhir/Patient to see a list of patients, e.g. with Postman:

 

Deploying Firely Vonk

Vonk is a commercial server, but you can download binaries and a trial license. Because you need to register to get binaries and license, the templates do not deploy the server binaries themselves. However, they set up frontend and backend including all app settings for the web app. Since Cosmos DB is not officially supported, we will be using the template for Vonk with Azure SQL backend. Use the deploy buttons in the GitHub repository to deploy the infrastructure and once completed (should be 5 minutes or so), download the Vonk binaries and the trial license file.

The file with the binaries is called vonk_distribution.zip and you can add your trial license to the package by simply dragging and dropping it onto the zip file. After adding the license file, go to the Kudu console of the deployed web app and use "Zip Push Deploy" from the tools menu to deploy the application.

Once the application is deployed, you can check the front page of the server:

The Vonk server does  not have an easy initialization endpoint like Spark, but you can upload some sample data. There are some detailed instructions in the repo on how to do that.

Preloading of data is disabled in the default configuration, so you have to go to the app settings of the web app and disable the exclusion of the preload command:

 

You do that by changing the "preload" to "preloadXXX" and restarting the Web App. Don't forget to set it back when you are done loading data.

You can find data at https://www.hl7.org/fhir/examples-json.zip. That is a pretty big file and you may have problems with the upload timing out depending on the size of the resources you have deployed and the network speed, so I recommend chopping the file into some smaller bits and uploading. Here is how to do that with PowerShell:

[ps]
#Get the data an unzip
Invoke-WebRequest -Uri https://www.hl7.org/fhir/examples-json.zip -OutFile examples-json.zip
New-Item -Type Directory example-json
Expand-Archive -OutputPath .\example-json -Path .\examples-json.zip -ShowProgress

#Then create new zip files with chunks:
$chunkSize = 100
$files = Get-ChildItem .\example-json\*.json
New-Item -Type Directory ".\example-json-files"

$length = $files.Length
$fileCount = 0
for ($index = 0; $index -lt $length; $index += $chunkSize)
{
$zipFileName = ".\example-json-files\example-json-" + $fileCount + ".zip"
$filesToZip = $files[$index..($index+$chunkSize-1)] | Select-Object -ExpandProperty FullName
Compress-Archive -Path $filesToZip -DestinationPath $zipFileName
$fileCount++
}

#Send them to the FHIR server:
$zips = Get-ChildItem .\example-json-files\*.zip
foreach ($z in $zips)
{
Write-Host "Processing file" $z.FullName
Invoke-WebRequest -Method Post -Uri https://VONK-SERVER-URL/administration/preload -InFile $z.FullName -ContentType "application/octet-stream"
}
[/ps]

After this you have a Vonk server with preloaded data ready for testing.

Conclusions

This blog demonstrates how to run a FHIR server using PaaS services in Azure. The configuration with Web App frontend and Azure SQL Database backend could potentially be used for production use. The templates have been tested in Azure Government where the Web App and Azure SQL services are covered by the FedRAMP High platform ATO.