The problem
The distributor's order-management system — ASP.NET on .NET Framework 4.x — had run for twelve years on a physical server in the office. Deploys meant copying files over RDP on a quiet afternoon and hoping. Backups were a scheduled task nobody had tested. The developer who knew the codebase had left; the business depended on an app nobody dared touch.
The approach
No big-bang rewrite — the app made money every day and had to keep doing so:
- Stabilise first — before changing anything: source control cleanup, a working local build, and a smoke-test suite around the critical paths (orders in, invoices out).
- Port incrementally — the codebase moved to ASP.NET Core (.NET 8) module by module, data access landing on Entity Framework Core. Each ported module shipped behind the same URLs, so users never noticed.
- Azure, described as code — App Service with staging slots, Azure SQL with automated, point-in-time backups, and the whole environment defined in Bicep so it can be rebuilt from the repository.
- A pipeline instead of a ritual — GitHub Actions builds, runs the tests, deploys to the staging slot, and swaps to production. Rolling back is swapping back — a one-minute, one-click operation.
- Eyes on it — Application Insights dashboards and alerts replaced "wait until someone from sales calls".
The result
Deploys went from a nervous afternoon to a ten-minute pipeline run that happens whenever a change is ready. The monthly hosting bill came in about 40% under the old server's real cost once maintenance was counted, restore procedures are now tested instead of assumed, and the company no longer depends on one machine under the stairs — or on one person's memory.