All posts

The Boring Parts of Cloud Migration

Cloud migration blog posts usually focus on the architecture: Azure Functions here, API Management there, containers, microservices, the whole diagram. Those posts aren't wrong. But they skip the 80% of the work that's not architecture. It's the boring parts.

Inventory is the actual first step

Before you migrate anything, you need to know what you have. At UNAIDS, "20+ enterprise systems" was the official count. The real count was higher because nobody counted the spreadsheet-based workflows, the Access databases on someone's desktop, and the SharePoint sites that had quietly become mission-critical applications.

I spent weeks doing discovery. Not exciting weeks. Weeks of meetings, screenshots, "who owns this?", "what happens if this goes down?", and "wait, that's still running?" The inventory doc was the most important deliverable of the entire migration, and it had zero technical complexity.

Dependencies are invisible until they break

System A sends a nightly file to System B. System B triggers a Logic App that updates System C. System C has a hardcoded reference to the on-prem SQL Server IP address. Nobody documented any of this because it all just worked.

You find out about these dependencies when you migrate System A and System C stops working two days later. The connection between them went through System B, which you weren't planning to migrate until next quarter. Now you're debugging a production issue that spans three systems you've never seen together.

The fix: map dependencies before you move anything. Talk to users. Check connection strings. Look at scheduled tasks. Assume every system talks to at least two others and that none of it is documented.

People migration is harder than system migration

Moving a .NET app to Azure App Service is a solved problem. Getting the finance team to trust the new system — that's the unsolved one. People who've used the same application for five years don't care that it's now running on Azure. They care that the button they click every Monday morning is in the same place and works the same way.

We learned to do migration in phases with extensive parallel running. The old system stays live while the new one proves itself. Only when the users are comfortable do we cut over. It's slower and more expensive than a hard cutover, but it's the only approach that doesn't generate a flood of support tickets and erode trust.

The payoff is real but delayed

After a year of migration work, the improvements are tangible. Better reliability, actual disaster recovery capability, proper monitoring, cost visibility. But the satisfaction comes slowly. Nobody celebrates a migration that went smoothly — they only notice when things break. The best outcome is that nothing happens, and "nothing happened" is a hard thing to take credit for.