Migrating .NET apps and SQL databases to Azure
When planning a migration of .NET apps with associated SQL databases to Azure, you generally have two options:
- Azure IaaS with Azure VMs and VM scale sets running SQL Server or any other supported SQL DBMS (e.g. MySQL Server)
- Azure PaaS with Azure App Service and Azure SQL or other supported PaaS-based SQL service (e.g. Azure database for MySQL)
It is important to take the time to carry out proper planning and actively engage with the software development and systems engineering teams from the very beginning, in order to deeply grasp the customer’s source environment as well as their technical and business challenges and requirements.
.NET apps and SQL databases migration considerations
Running a migration project entails many challenges as well as preparation and execution phases. The high level steps of a .NET app and associated SQL database migration to Azure PaaS services are provided below:
- Carry out proper planning and architecture design of the overall solution. There are few important items which you should take into consideration when designing the migration solution. Design considerations for Azure App Service as well as design considerations for Azure database for MySQL should be taken into account at an early phase. If you are considering Azure SQL database vs. SQL Server on Azure VMs, you should definitely consider reviewing this blog post about selecting the proper Azure SQL service for your workloads. Your design should take into account fundamental aspects such as functionality, performance, security and fault tolerance (redundancy) and disaster recovery. Redundancy considerations for Azure App service have been discussed in another blog post. Also a separate blog post covers redundancy considerations for the Azure database for MySQL.
- Create your target Azure tenant, target management groups, target subscriptions and target resource groups. Decide upon authoring an ARM/Bicep template vs. creating the required Azure resources via the management portal/Powershell/CLI/Cloud shell. When all resources have been provisioned, consider exporting and saving all relevant ARM templates, so that you can easily recreate your infrastructure if you need to in the future.
- Identity source environment component versions and confirm compatibility of the source environment versions with the target environment. For instance, if you are running ASP.NET apps with a version prior to .NET 4.8 (officially supported by Azure App Service) you should be fine migrating them to Azure, as long as necessary considerations are made. Review the following blog post about running older .NET app versions on Azure App Service. Same version compatibility considerations should be made for all components in-scope for the migration, for instance MySQL Server version, MySQL server engine and server parameters.
- Decide whether you will be using Azure CAF/WAF best practices, such as using Azure Blueprints, Azure policies and Azure landing zones for your migration.
- After all Azure resources have been provisioned, validate that you can access the target Azure infrastructure by using common Azure management tools, including the Azure management portal, Azure Powershell, Azure CLI, Azure Graph/ARM REST API as well as various service-specific client tools. In the case of .NET apps, you should be using Visual Studio or Visual Studio code and in the case of MySQL you should be using MySQL Workbench and MySQL CLI tools, such as mysql and mysqldump.
- Define which workloads will be migrated first and carry out a proof of concept migration first, during which you will perform functional, performance, security and disaster recovery testing in at least one representative workload from all the types of workloads which are to be migrated.
- Start with the SQL databases first. Stop all traffic towards the database(s) to be migrated and close all active connections from users and clients.
- For databases, decide upon an online vs. offline migration method. There is good documentation by Microsoft available in the following guides: https://docs.microsoft.com/en-us/data-migration/.
- Ensure that all target SQL Server or MySQL server parameters in Azure are identical to the ones in your source environment. Or make necessary assumptions for setting a different value in some server parameters.
- Create empty databases in the target environment. Start migrating the database schema, objects and data. For example, in MySQL offline migration, prefer using MySQLDump to export your databases and import them to the target Azure environment. Validate connection to the database after the migration by using either SQL Server Management Studio or MySQL Workbench.
- For .NET apps, prefer using Visual Studio for publishing your apps to Azure App Service. Take special notice of of the connection string to update in your application code. You can make use of publishing profiles (one JSON file per Azure App service deployment slot) or use the publish to Azure option inside your VS project.
- After your .NET apps are deployed to Azure, create the recommended deployment slots for each App Service (for example staging and dev).
- Activate App Insights for all your App Services. Remember that this requires the provisioning of an Azure Log Analytics Workspace resource.
- Configure all relevant App settings and general settings under each of your Azure App service resources (including publish profiles and FTPS deployment credentials).
- Enable and configure Visual Studio remote debugging for your Azure App Services.
- Thoroughly test all PoC apps by carrying out functional and performance/security testing and review all AppInsights metrics as well as the App Service and SQL database logs.
- After establishing your database and application tiers, it’s time to add your front-end tier. Make use of Azure Front Door, Azure Traffic Manager or Azure Application Gateway with Azure App Firewall to add security and load balancing to your Apps. Include DNS and TLS considerations in this configuration.
- Carry out network connectivity configurations to eliminate public access to your resources. Initially you may have used the public endpoints of the App Service and of the Azure SQL database or Azure database for MySQL service. At this point, you should disable public access and configure private endpoints to your target Azure resources from your internal Azure VNETs. As an example, follow instructions for configuring private endpoints in Azure App Service and Azure database for MySQL. Configure VPN connectivity to your on-premise environment (via S2S VPN or P2S VPN) so that your admins can manage all target Azure resources via VPN network.