Common architectural patterns of application modernization
Each application potentially brings unique considerations and challenges, but some common architectural guidance is presented here to aid technologists in understanding how application modernization is implemented.
Multi-use databases that were lifted and shifted may be running standalone on EC2 instances. This self-managed configuration still requires dba support for backups, disk space and health monitoring. Licensing issues may be a motivating factor as companies seek to fully consume existing licenses. Migrating self-managed databases to fully managed database services provides better durability and reliability as well as eliminating database infrastructure support needs.
Many legacy applications implement a tiered architecture often consisting of a data persistence layer, a business logic layer, and an interface.
There are limited migration paths for the data persistence layer. If the database is self-managed running on an EC2 instance or even if it was originally migrated to an RDS instance, a clustered relational database that can scale horizontally like Aurora Serverless may be appropriate.
At the business logic layer, heavy components written in Java or C# that are stateful and tightly coupled to the other application tiers are likely to appear. This architecture does not scale. A modern architecture might implement this as a microservices architecture or a stateless application hosted in an autoscaling group behind a load balancer. Serverless and event-driven architectures utilizing Lambdas, SQS, and application triggers may also be used.
The Service Oriented Architectures (SOA) that rose to prominence in the 2000s has been replaced by microservices architecture theory. Bulky monolithic services are decomposed into separate, more granular services where each service does a lot less. This paradigm shift is motivated by the single responsibility principle, which states that “every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated.” While a microservice may group functionality together where appropriate this provides insight into the guiding tendency to decouple previously coupled services.
A consequence of microservice architecture is that requests are processed asynchronously, making applications more responsive, and allowing any service disruptions to recover gracefully.
Batch vs Streaming Architectures
Another common pattern for application modernization is the conversion of batch to streaming data architectures. This is often driven by business cases requiring a shorter time to answer than what is currently possible with a batch architecture. Streaming architectures decouple publishing from consuming, adding asynchronous access and flexibility to any downstream data processing.
Containerization & DevOps
Containerization is an imperative in the application modernization context. What containerization allows is the full separation of concerns: infrastructure, application services, and data.
Defining infrastructure as code ensures that the infrastructure the application runs on can be reproduced with 100% fidelity while managing any modifications through traditional software configuration management practices. Containerizing the application code allows it to be deployed to various infrastructures, including on premises as part of a hybrid cloud.
Implementing CI/CD pipelines for the application code ensures that the application is fully decoupled from its infrastructure, unit testing and regression testing can be automated, and if desired, releases also can be scheduled and deployments automated.
The cloud ecosystem and the use of these different strategies, services, and tools means that better monitoring, logging, and alerting is easily achievable. Better capabilities in this area means fewer IT resources are needed to manage an expanding portfolio of applications, freeing resources to solve the next business problems.