Home / Azure

AzureHow-toIntermediate

Transformation: move IIS and .NET web apps from VMs to Azure App Service

Replatform ASP.NET and ASP.NET Core sites from IIS on Windows VMs to Azure App Service. Assess compatibility, handle config, certificates, file system and Windows auth differences, migrate with slots and cut over safely.

Deepak Bhardwaj3 min read

Applies toAzure App Service (Windows and Linux), ASP.NET Framework 4.x, ASP.NET Core 8+, IIS 8.5+

Why bother

Moving off IIS VMs removes OS patching, IIS configuration drift and manual scaling. App Service gives you slots, autoscale, managed certificates and built-in authentication. Most line-of-business sites move with few code changes if you check the blockers first.

1. Assess

Use the App Service migration assessment (Azure Migrate web app discovery or the App Service Migration Assistant) against your IIS servers. Then check these by hand:

Blocker App Service answer
Writes to local disk (uploads, logs) Azure Storage (Blob) or mounted Azure Files; local disk is not persistent across instances
Windows authentication (Kerberos/NTLM) Entra ID authentication (Easy Auth or MSAL in code)
GAC assemblies, COM components, MSI installers Not supported — refactor or use Windows containers
Registry access, Windows services, scheduled tasks WebJobs, Azure Functions or a separate worker
Connects to on-prem SQL or file shares VNet integration + hybrid connectivity, or Hybrid Connections
Custom IIS modules / URL Rewrite rules web.config rewrite rules work on Windows plans; native modules need containers

2. Prepare the target

az appservice plan create -g rg-web -n asp-web-prod --sku P1v3 --is-linux false
az webapp create -g rg-web -p asp-web-prod -n app-intranet-prod --runtime "dotnet:8"
az webapp vnet-integration add -g rg-web -n app-intranet-prod --vnet vnet-spoke-web --subnet snet-appsvc-int
az webapp identity assign -g rg-web -n app-intranet-prod

For .NET Framework apps, use a Windows plan and pick the ASP.NET 4.8 runtime stack.

3. Move configuration out of the box

  • Connection strings and app settings → App Service configuration with Key Vault references.
  • web.config transforms → environment-specific app settings.
  • Machine keys (for forms auth / view state across instances) → set explicitly or move to Data Protection keys in Blob storage for ASP.NET Core.

4. Deploy to a staging slot

az webapp deployment slot create -g rg-web -n app-intranet-prod --slot staging
az webapp deploy -g rg-web -n app-intranet-prod --slot staging --src-path ./publish.zip --type zip

Test functionally against the real backends via VNet integration.

5. Certificates and domains

az webapp config hostname add -g rg-web --webapp-name app-intranet-prod --hostname intranet.contoso.com
az webapp config ssl create -g rg-web -n app-intranet-prod --hostname intranet.contoso.com   # free managed cert

Use a Key Vault certificate instead for wildcard or EV certificates.

6. Cut over

  1. Lower DNS TTL in advance.
  2. Freeze content changes on the IIS server; copy final uploads to Blob.
  3. Swap staging to production, then switch DNS (or move the hostname in Front Door / Application Gateway).
  4. Keep the IIS VM stopped but intact for the rollback window.

Tip

Put Front Door or Application Gateway in front of both old and new sites before cutover. Then the switch is a backend change with instant rollback, not a DNS change.

Checklist

  • No local disk writes, COM or GAC dependencies left
  • Authentication moved to Entra ID
  • Secrets in Key Vault, managed identity used for Azure resources
  • Health check path and autoscale rules set
  • Logs to Application Insights; old VM decommissioned after soak