Cloud migration is a challenging process for many companies, as they try to move apps, data and processes from on-premises data centers to cloud providers without impacting customers, analysts and IT processes in terms of security and privacy. This paper will cover the most efficient cloud migration strategies, along with challenges across different phases and constraints that may be encountered during the migration of over 60 apps from multiple data centers to the cloud. If you are starting or currently in the process of migration, these strategies will help validate approaches and serve as a basis for comparison with best practices.
Challenges
The team faced the following challenges during the migration process: Lack of cloud knowledge, documentation gaps, third-party software compatibility, large volumes of data movement, file shares with AD and database-specific ETL processes.
Firstly, the teams lacked thorough knowledge regarding AWS cloud concepts, many of which were crucial, such as infrastructure as code (IAC) and DevOps pipelines. The time required to learn and apply these concepts led to delays in the migration; thus, blogs and starter kits were created to alleviate the issues. Another challenge was third-party software compatibility, since the older software was not compatible with cloud-native deployments. As a result, a brand-new system had to be developed to migrate users and data to the new system, while retiring the old one. In some cases, we used the lift-and-shift method, applying the same code and images. More about this is included in the ‘solutions’ section.
Another significant element to consider was the large volume of data that needed to be moved with data integrity. Data loss is detrimental to the productivity and accuracy of the migration, mainly because it can affect the user experience. To mitigate potential data loss, we used AWS DataSync to synchronize data between on-premises and the cloud, and vice versa. The synchronization streamlined the process while simultaneously providing a safety net in case of errors.
Solutions
A methodology was designed to prevent various issues before they arise. The main idea was to prepare the current architecture so that the team understands the benchmark required to maintain the current status quo. Along with understanding the current architecture, we documented special requirements and mapped them at a component level to ensure the migration doesn’t disrupt niche processes. Noting existing customers, workflows, their functional and non-functional requirements and service level agreements (SLAs) helped us ensure that the new system meets the same criteria before the final release.
According to the methodology, data layer, compute and access requirements are mapped to the project requirements using the following three primary strategies:
- Cloud-Native Architecture
We designed the systems to use modern data stores such as S3 buckets, EFS, FSx, DynamoDB and global RDS instances. These data stores — especially S3 buckets — have the highest durability and efficiency. Compute is designed to use Lambda, Fargate and EKS containers to optimize costs and scale compute to meet application/user demands.
- Hybrid
In cases of compatibility issues, we used cloud-native solutions, leaving most components as is. This strategy allowed us to expedite the migration process in an iterative, incremental manner to keep up with the project schedule.
- Lift-and-Shift
Some portions of the applications were too old, using outdated software and libraries. In this scenario, we couldn’t afford to spend too much time rewriting or rearchitecting the systems. Therefore, we used the lift-and-shift method to complete the migration first and then incrementally moved to cloud-native solutions. In fact, we even retired 2–3 applications and built entirely new platforms to support the migration.
Desktop-based Citrix solutions were migrated to AWS AppStream, enabling users to maintain the same experience without workflow interruptions.
We created infrastructure using Terraform and CloudFormation with DevOps pipelines. By developing reusable Terraform templates as well as RBAC and ABAC access policies, we were able to implement Cloud Custodian to monitor newly created resources and take the necessary steps. Therefore, owners were alerted if the resources they made in the cloud were not used or had security vulnerabilities, potentially incurring additional costs and risking the AWS cloud environment.
To prevent any potential challenges, we defined service control policies (SCPs) to restrict actions that are risky to apply. Additionally, by configuring virtual teams and single sign-on (SSO) roles to onboard new teams, we increased efficiency while enabling teams to create their own infrastructure easily and independently.
Lastly, to focus on the team’s work ethic during the migration, weekly communication meetings were scheduled to discuss the best practices and cloud governance. These meetings helped raise awareness and ensure that the team members followed through.
Lessons Learned
The most impactful lesson learned was to build the current architecture and documentation before the actual migration. This action helped us understand the application better and select the right cloud migration strategy. Doing this before the migration will help streamline the entire process.
Developing reusable starter kits, Terraform modules and familiar DevOps practices helped various teams get started and follow the guidelines we set. Additionally, the onboarding process can be replicated for future migrations to ensure consistent workflows and efficient resource tagging.
Creating Cloud Custodian policies and monitoring to enforce best practices in tagging and cost management was a crucial breakthrough for me, as it enabled the team to manage security vulnerabilities and patching schedules.
We created an autonomous environment to provision and manage cloud resources effectively without involving TechOps teams, enabling the timely deployment of new releases.
Conclusion
Ultimately, cloud migration may seem daunting because of various challenges that affect user experience and data integrity. However, by utilizing the strategies and lessons, future projects can be streamlined to maximize efficiency.

