Microsoft teamed up with SnapMD—an LA-based startup—to migrate their technology stack from a private server to Microsoft Azure and to take advantage of Azure platform-as-a-service features to host their core workloads.

Core team:

  • Dan Parker – Application Developer, SnapMD
  • Michael Johnson – Lead Network Architect & SysOps, SnapMD
  • Jay Lee – Lead Engineer, SnapMD
  • Daniel Bouganim – CTO, SnapMD
  • Anthony Kelani (@akelani) – Technical Evangelist, Startups, Microsoft

During the course of three days, we worked together to migrate their application from virtual machines (VMs) running on private servers to the fully managed Azure App Service, and converted one of their daily user-account cleaning processes to scalable code in Azure Functions.

Customer profile

SnapMD is a Los Angeles–based emerging healthcare IT growth company that has designed and developed its Virtual Care Management (VCM) telemedicine platform enabling healthcare providers to engage their patients via a highly-secure, HIPAA-compliant, cloud-based true point-of-care platform with powerful back-end systems to manage the digital health enterprise. SnapMD offers all the software and services that healthcare providers need to improve access to convenient and effective care. The robust, scalable, private-label VCM platform is designed to handle multiple service-lines, and can be deployed as a single telehealth platform across the enterprise.

Problem statement

Existing SnapMD web and back-end applications were hosted on a private server with VMs managed by their development team. They were also using Microsoft SQL Server 2008 on a VM. SnapMD requested a solution to reduce cost and overhead involved with managing private servers and VMs. SnapMD also started selling to more customers overseas and needed a secure, geo-scalable solution that would deliver their services to their foreign customers. They were also deploying to their production server manually, which caused at least 1 hour of downtime with each new deployment. They wanted a solution that integrated well with a continuous-delivery tool, so they could maintain separate environments and deploy to production with zero downtime.

Solutions, steps, and delivery

The Microsoft Startup team met SnapMD at a Microsoft-sponsored networking event in LA. Their CTO was very interested in Microsoft cloud offerings because SnapMD application uses .NET and SQL Server. Our team gave them an overview of Azure App Service, Azure Functions, and Visual Studio Team Services. They were quite satisfied with our solution, and we scheduled a hackfest to migrate their stack to Azure.


Microsoft technical evangelist Anthony Kelani and the SnapMD development team first did a review of the current SnapMD infrastructure. The SnapMD stack consisted of an MVC web application, a .NET API application, a SQL Server 2008 database, AWS S3, and other processes that took care of tasks such as deactivating unconfirmed accounts and sending push notifications to mobile devices.

Architecture diagram: SnapMD before Azure

We identified what needed to be refactored in their application in preparation for the migration. Their application was using MSMQ, and SnapMD decided to refactor their application to use Redis instead.

We created an architecture diagram of the solution that we would deploy to Azure.

Architecture diagram: SnapMD on Azure

Azure App Service

Our first task was migrating the SnapMD application over to Azure App Service. We first set up an App Service plan and then created tSo App service apps, one for web and one for the API.

We used Visual Studio to deploy the web app to the web App Service.

SnapMD on Azure: web App Service portal

We then deployed the API app to the API App Service.

SnapMD on Azure: API App Service portal

We had to add a few configurations to get the application to work. We added the connection strings for the database and Redis to the API application settings.

SnapMD on Azure: API application settings

We then tested the App Service scale-out feature by manually scaling up the API instance to two instances.

SnapMD on Azure: API App Service scaled up

Getting things to work required a small bit of refactoring of their application, but by the end of the day we could bring up the web application in a browser, which confirmed that the web application and API application were working.

SnapMD web login page

SnapMD web registration page

SnapMD web Terms & Condition page

Azure database migration

Michael Johnson, Lead Network Architect & SysOps for SnapMD, created a Redis cache and Azure SQL Database V12 service for us to migrate over sample data from the SnapMD staging environment. The SnapMD staging data was on SQL Server 2008, so first we exported a .BACPAC file and tried using the SqlPackage.exe CLI tool to import the .BACPAC file into SQL Database. We had some issues with the tool freezing and not having a progress bar, so we uploaded the .BACPAC file to an Azure Storage blob container and used the Azure portal to import the blob into SQL Database.

SnapMD on Azure: SQL Server

SnapMD on Azure: SQL Database

We then tested logging into the web application and navigating to a few pages to verify that the connection to the database was working.

Azure Functions

The SnapMD platform also had a process that runs in a VM to perform 22 different periodic database tasks, such as log cleaning, email reminders, and SMS triggers. The task of periodically cleaning up unverified accounts was a perfect scenario for an Azure function that could utilize a timer trigger, so we converted this task to a JavaScript Azure function. The function would run daily, connect to the SnapMD database, and deactivate accounts for which a user hadn’t verified their email within 24 hours.

In each Azure function, there is a function.json file that specifies the function’s bindings.

The Azure function we created takes a timer input, where the schedule property tells the function when to run. In our case, the function is set to run every 24 hours.

    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in",
    "schedule": "0 0 * * * *"

The Azure portal allows you to specify the input and output bindings on the Integrate tab (shown in the following image) and generates function.json for you. You can edit function.json either directly or through the portal.

Function trigger: Timer

SnapMD account-cleanup function trigger

Function code

SnapMD Account Cleanup Function Code

In index.js, we connect to the database—

var conn_str = process.env["sqldb_connection"] + ";Encrypt=true";

—and deactivate the user accounts that haven’t been verified:

var query = 
        `UPDATE UserTokens AS t ` +
        `INNER JOIN Users AS u ` +
        `ON t.UserId = u.UserId ` +
        `SET u.IsActive = 'I', u.UpdateDate = '${modifiedDate}', t.TokenStatus = 'I' ` +
        `WHERE TokenStatus = 'A' AND u.CreateDate < '${notVerifiedTime}' AND u.CreateDate > '${gracePeriod}' AND ` +
        `(CodeSetId = ${newUserRegistrationCodeSetId} OR CodeSetId = ${newUserOnboardTokenCodeSetId})`

Customer example

Here is the SnapMD application running on Azure, with screen shots of both the patient portal and the doctor portal.

Patient portal

SnapMD patient portal

SnapMD patient portal

SnapMD patient portal

Doctor portal

SnapMD doctor portal

SnapMD doctor portal


The migration of SnapMD to Azure was a major success, and the team was very satisfied with the transition. During the next few weeks, the team plans on making tweaks, fully setting up CI/CD with Visual Studio Team Services for their various environments, and converting their task processes to Azure Functions.

“Our telemedicine platform offers a multifaceted approach to healthcare delivery, including real-time communication, collaboration, and messaging, clinical management, practice and patient administration, and a configurable rules engine. Given the HIPAA regulatory requirements and our need for scalability, redundancy, and security in order to support clinicians and their patients, regardless of their geographic location, SnapMD’s move to Azure is quite an undertaking. However, with Anthony Kelani and the rest of the team from Microsoft, this task has been easy! We engaged in a 3-day hackfest and, in that short time, managed to create a pilot platform on Azure that included DevOps, the Azure application API, conversion of a service module into an Azure function, provisioning of blob file storage, and initial file migration. This transition has significant importance to us as we continue to expand our product offering, and with the guidance and support we received from Microsoft, we couldn’t be happier with our progress!” —Daniel Bouganim, CTO

Additional resources

Documentation used for the migration from SQL Server 2008 to Azure SQL Database: