Replatforming and Rearchitecing with Serverless Event-based Architecture Approach

Marin Radjenovic
Crayon Data & AI
Published in
9 min readAug 21, 2023

Web businesses that run successfully for several years or even a decade can experience the tiredness of perpetual growth. That is usually caused by multiple factors such as technical debt, expensive and exhausting support, lack of automatization, old tech-stacks, and finally keeping and hiring adequate staff. At that time, migrating to a cloud provider such as AWS, gives your application more maneuvering space and the ability to evolve.

Replatforming the solution very often can be simple. By moving your application to AWS services such as Elastic Beanstalk and RDS, you are able to quickly spot benefits like automated backups, automated scaling, point-in-time recovery, and so on. However, the real benefit comes when you sprinkle some of the cloud native s erverless services into existing applications with some simple rearchitecting/refactoring approaches.

Photo by Annie Spratt on Unsplash

Intro

Most web applications today are basic 3-tier web applications. A 3-tier web application is a software architecture consisting of three layers: presentation, logic, and data. The presentation tier handles user interface interactions, the logic tier manages application processes, and the data tier stores and retrieves information from databases. At the time, 3-tier web applications offered better scalability, maintainability, and separation of concerns than coupled application architectures.
As mentioned before, there were multiple reasons over the years which sounded the alarm that it was time for some changes. One obvious choice is to utilize automated/managed services that can be found on cloud providers such as AWS. By moving to the cloud, the cost of operating the environments drops significantly.

AWS Migration Strategies

Depending on what you would like to achieve, the complexity of migrating to the cloud can vary. AWS offers 6 strategies for migrating to the cloud that can lead to a planned successful migration.

1. Rehost (lift and shift): This strategy involves moving applications and data from on-premises to AWS without significant modifications. It offers rapid migration, but may not leverage the full potential of cloud services.

2. Replatform (lift, tinker, and shift): This approach involves making minor adjustments to applications for better compatibility with AWS services while maintaining core architecture. It offers a balance between migration speed and optimization.

3. Repurchase (drop and shop): Organizations replace their existing applications with new cloud-native alternatives available in the AWS marketplace. This strategy is suitable when existing applications don’t align with cloud best practices.

4. Refactor / Re-architect: In this strategy, applications are redesigned or rebuilt to take full advantage of AWS cloud services. It offers the highest level of optimization and scalability, but demands more development effort.

5. Retire: This involves identifying and retiring redundant or obsolete applications, reducing operational overhead, and costs.

6. Retain / Revisit: Some applications might not be immediately suitable for migration due to complexity or compliance concerns. Organizations can choose to retain them on-premises or revisit migration options later.

Choosing the right strategy depends on business goals, application complexity, timeline, and desired cloud benefits. A well-planned migration strategy ensures a smooth transition to AWS while optimizing performance, scalability, and cost efficiency.
As we are considering 3-tier web applications, let’s focus on 2 migration strategies; Replatforming and Rearchitecting/Refactoring. The other strategy called Rehosting will not provide automatization and significant reduction in operational requirements that are currently an issue.

Replatforming 3-tier web applications

I will briefly explain how my team and I replatformed our application 3-tier application. As mentioned above, a 3-tier web application consists of three layers: presentation, logic, and data.

image source: https://inui.io/basic-sap-terms/

Naturally, we are considering Application Server and Database for migration as they currently require the most attention when it comes to operational needs and effort. For application server we have selected AWS Elastic Beanstalk and for the database platform, we have selected RDS. So let’s discuss the reasoning behind the decision.

AWS Elastic Beanstalk offers a solution for replatforming our web application because of its ease of use, scalability, and management capabilities. By migrating to Elastic Beanstalk, we can modernize our application architecture without the complexity of managing the underlying infrastructure. In essence, Elastic Beanstalk offers support for multiple programming languages, as well as docker containers. Furthermore, it manages Elastic Load Balancer, autoscaling, and it is directly integrated with Cloudwatch.
A significant benefit is that the deployment process is done in the same way as on-prem. The web application is in Java so the WAR file has been built and deployed to the Tomcat server on Elastic Beanstalk in the exactly same way as before.

Regarding the database, the obvious choice was PostgreSQL RDS. By switching to RDS, our application is benefitting from Multi-AZ deployment which ensures high availability and fault tolerance. Furthermore, our application gains access to automatic backups, security features, and scaling capabilities such as the effortless creation of read replicas.

The infrastructure of the replatformed solution looked like as shown in the above diagram. The networking part was created using Terraform templates. It included VPC, Subnets, and Security Groups in 2 availability zones. While EC2 instances, autoscaling, load balancer, and S3 buckets for application deployments were managed by Elastic Beanstalk.

RDS was deployed using terraform scripts. It is worth mentioning that Elastic Beanstalk could have also managed it, however, we prefer full control over RDS.

With the above approach, we have successfully migrated and replatformed our application.

There are multiple improvements that we gained by re-platforming :

  • With elastic beanstalk, autoscaling was gained with almost no effort, as well as monitoring the instances and logging on the application level.
  • With RDS there were numerous benefits like automatization of backups, point-in-time recovery, DB monitoring and etc.
  • Finally, the biggest gain was using managed services that reduced operational effort and provided the ability to integrate with other AWS services.

Refactoring/Rearchitecting to cloud-native development

Refactoring and Rearchitetcing the solution, in essence, means that applications are redesigned or rebuilt to take full advantage of AWS cloud services. This sounds like a lot of unpredictable long-lasting work. That might be correct in some circumstances, however, before we start discussing the reasoning, let’s talk about serverless adoption strategies.

1. Leapfrog Strategy: A transformation approach where legacy systems are bypassed, and new technology is directly adopted to achieve rapid innovation. This involves skipping intermediate steps and adopting advanced solutions to gain a competitive edge.

2. Organic Strategy: A gradual modernization method that integrates new technologies into existing systems over time. This strategy focuses on incremental changes to enhance functionality and maintain stability, while accommodating evolving business needs.

3. Strangler Strategy: A migration plan involving gradual replacement of legacy components with cloud-native or serverless alternatives. New functionalities are added in a “strangling” manner until the legacy system is phased out, reducing risk and ensuring a seamless transition.

How to choose an adequate strategy?

All 3 strategies can be good or bad depending on the circumstances and timeline.

Leapfrog Strategy can be useful, in cases where the only option is to bypass the application that has become hard or impossible to maintain. In that case, the best option is to rebuild the application using modern tech-stack and modern architectures.
Developing a fully cloud-native solution (or in other words Serverless) makes this strategy a good way forward because of instant scaling and pay-as-you-go benefits. However, in our case, we do not want to rebuild the application. Such a step would be unnecessary and rather expensive at this moment. What is expected is just an improvement of features on an already existing solution.

What we are looking for is better defined as a mixture of Organic & Strangler Strategies. By using Elastic Beanstalk we are already using Cloudwatch to monitor the servers and the application performance. We can utilize Couldwatch logs and alarms so that we are completely aware of the application state. By using Cloudwatch which is a fully managed service, we started injecting certain managed services in order to improve the current application. With that said we have utilized Organic Strategy.
However, in order to provide new features to the customers while using current data it is necessary to do some refactoring and rearchitecting.
Strangler strategy
does concern the actual improvement of already existing features of the application via the gradual replacement of certain legacy or bottleneck features of the application. In order, to create new features or replace existing ones utilizing cloud-native services, it is important to identify and create events from the web application.

Rearchitecting for Event-Based architecture

Event-based architecture is a design approach where software components communicate through events, to trigger actions and responses. Events represent occurrences like user actions or system updates, enabling loosely coupled systems to communicate and scale efficiently. This architecture is based on modularity, flexibility, and real-time responsiveness by decoupling components. Such an approach results in easier maintenance and integration with other AWS Services. Decoupling already existing monolith 3-tier web applications, in order to be event-based, sounds like a serious undertaking. Well, we do not need to do it all at once but instead focus on gradual migration. With that said, it is important to identify which logical entities in the application should be considered so that we can create events on certain actions like create, update, delete, and so on.

In order to better explain the idea of how to identify the logical entities that should be aimed for the creation of events, I will need to explain the business concepts of our application.
Our application supports simple factory production processes where both customers and the staff are involved to be aware of the timelines and potential delays. The logical entity that the whole application is based on is the Task entity (similarly JIRA is based on the concept of task). Task entity has many changes during the process, such as created, scheduled, rescheduled, in-progress, completed and etc.
Changes on the task entity itself are important in order to create proper notifications to the customer staff, make 3rd party application integrations, data analytics, and so on.

In order to create events and listen to Task entity changes, there should be changes made on the Application level or Database level. The application level seemed quite complex as multiple parts of the application needed to be modified. However, Database changes can be implemented rather quickly on the table level using DB triggers.

Introducing Event-based architecture on the monolith 3-tire web application

Database triggers are predefined actions that automatically execute in response to specific events such as INSERT, UPDATE or DELETE. Using RDS for both PostgreSQL, MySQL, and Aurora(MySQL & PostgreSQL) there is direct integration with AWS services like S3 and Lambda.
Data can be imported and exported via S3 which is amazing for scenarios like Data Lake integrations and etc. Using Lambda and EventBridge, will enable the processing and preparing of data to be used by other AWS services. That feature opens up numerous possibilities for quick evolution of the application with new features.
With that said, as we are looking to create events out of the changes made to the Task table, AWS Lambda integration sounds like the perfect match.

The final solution is presented in the above diagram. Let me briefly explain the workflow:

1. RDS triggers the AWS Lambda (EventCreatorLambda) and is passing the inserted/updated/deleted data as JSON.

2. Such data is reformated and passed as an event message to EventBridge’s custom event bus. Steps 1 and 2 are presenting the core of the solution for further expansion.

3. NotificationLambda and CustomerIntegration lambda will be triggered by certain message types that are sent to the event bus.

4. NotificationLambda will publish an SNS message on a certain topic and notify all subscribers that are interested in that kind of event.

5. CustomerIntegrationLambda will notify the customer application over API webhooks.

With the above solution, we are creating a platform not just for the current requirements, but also for further expansion. Steps 1 and 2 are presenting the event creation mechanism that will be the fundament of our future event-based rearchitecting.

To be continued…

Please stand by for the next article, with implementation steps and code discussion.

--

--

Marin Radjenovic
Crayon Data & AI

Cloud Architect. Developer. 2x Father. 7x AWS certified. AWS Community Builder. AWS UG Montenegro founder 🇲🇪. Working for Crayon