Moving 40 applications from one cloud to another cloud is not always easy. We learned this by migrating from Azure to AWS. Our handicap: we had to partially build the migration tools ourselves. Discover what we learned from this assignment and the best approach, from what we know today, when moving from Azure to AWS.
Ok, first the elephant in the room. Why migrate from cloud to cloud if it is such a hard task? After all, most companies are just starting to migrate from on-premise to the cloud. Unfortunately, if you were one of the early adopters of the cloud, a lot has changed. All cloud providers that made it before to our client’s shortlist have reinvented themselves; each in their own way. This makes “cloud hopping” - as some call it - beneficial for many reasons:
For our client, the main reasons for migration were cost optimization and being less dependent on one provider.
“The biggest difference between on-premise to cloud and cloud to cloud migration is the technical side"
The lack of any complete out-of-the-box migration tool was one thing.
In addition, we faced another challenge: business continuity. It was the biggest priority for our client. This meant all applications should run all the time. Downtime was strictly limited to small maintenance windows during weekends, to keep the impact for end-users as small as possible.
Hence - functional improvements on the application were out of scope, unless there were some quick wins in cost; for example, reducing the size of the volumes or databases.
So, how do you make sure to deliver such a project?
We approached this by dividing responsibilities and making them clear for all involved parties. Some examples:
But more importantly: we followed below migration cycle (a factory approach).
For each application we followed this migration cycle.
It always starts with an assessment (see below form). We sit with each application owner and technical application manager, and take the time to talk about what the application does and what the interfaces are to the client’s network, and to other third-party tools. Together with the application owner we then decide which migration approach would fit the application best and what potential gaps we would need to close.
Choose any of the below migration approaches:
As a starting point, we were advised to go for the second migration approach, since this would result in the least down time. However, the application owners decided to go for the lift and shift method. This was mainly because the application documentation wasn’t always as crisp and clear as they hoped it was. The application was also installed by external parties, meaning reinstalling it would have become a time-consuming task for the application owner.
After deciding on the lift and shift strategy, we worked closely with the application owners. We organised multiple sessions to see how each application worked and since lift and shift comes with down time, we asked questions like: “Do we need a maintenance window for this application migration?”, “Can we do the migration during business hours?", “Are there existing maintenance windows we could use?” and “What is the best way to go live?”
When all decisions were made, it was time to plan and create the runbook with all the dependencies and parts to import. As you might notice, the starting point for a cloud to cloud migration is basically the same as for on-premise to cloud. The biggest difference is on the technical side.
“I had to rewrite the default migration scripting.”
Around 40 applications were selected to migrate to AWS. These applications were mainly built on Virtual Machines. That is why we focused on automating the Virtual Machines migration from Azure to AWS. There wasn’t an out-of-the-box tool available at that moment. However, by working closely with AWS, we were able to speed up the process. AWS provided us with input and examples on how to deal with VM migrations. Unfortunately, due to network specifics, some custom work was still required to automate the migration.
Our lift and shift migration consisted of three steps:
Converting the Azure application infrastructure (written in ARM) to AWS CloudFormation
This step could be prepared before or during the actual migration. Because we use a catalog way of deploying resources in the cloud, translating the Azure ARM code to AWS CloudFormation was relatively easy. It was as simple as picking a similar catalog item from the other cloud provider. During this stage, we didn’t pay attention to rightsizing or changing the infrastructure architecture. Instead we focused on getting the application up and running on the new cloud provider.
Running the automation pipeline with the parameters of the Virtual Machines to migrate
With help and input from AWS, we created the pipeline (see figure below) to do the actual migration. I will highlight the most important steps:
Deploy the CloudFormation template to create the new application resources
“1 terabyte? We can migrate that in two to maybe three hours. Let's say four to be sure”
So, now you know how we did it.
What are the takeaways when you do a cloud to cloud migration? These are the lessons learned from this project:
Even after planning every step of the migration (requesting change windows during- or after office-hours, and working together with the technical application owners), it’s not always possible to prevent issues from happening. For example, during some migrations problems occurred amid booting the migrated virtual machines. Being agile and in close contact with the project managers, technical application owners and the support team from AWS, we were able to come up with solutions for most of the issues.
Unfortunately, in a couple of situations the migration windows for the application were too limited and we had to perform a rollback to keep user impact to a minimum. At that moment it seemed like a big waste of time. But it was actually very helpful for us and the application owners because it gave us more insight in what the application was actually doing and how it was behaving on the OS. This new information helped in re-planning a new migration and helped to make it successful.
So in summary, a successful migration follows these steps: define the why, know your limitations, assess the situation, use a standard approach; then start, face the issues you encounter and handle them in an agile way.