Introduction
Serverless frameworks are gaining popularity for their cost-effectiveness, scalability, and rapid development capabilities and increasingly, many companies consider that the future of computing is serverless.
A serverless architecture represents an approach to creating and operating applications and services without the need for direct infrastructure management. Although serverless applications are ultimately executed on servers, the responsibility for overseeing these servers is shifted to a particular service provider, such as Amazon Web Services (AWS) utilizing 'lambda functions,' or Google Cloud Platform through 'Cloud functions.'
Effective migration is crucial to unlock the advantages of serverless architecture. Migrating existing applications or developing new ones in a serverless environment offers benefits like scalability, cost-efficiency, and simplified management. However, without a well-planned and executed migration strategy, organizations may struggle to realize these advantages. Effective migration ensures a smooth transition, minimizes disruption, and maximizes the potential of serverless computing for agility, cost savings, and improved performance.
The main goal of this article is to present the most relevant migration strategies to serverless applications. It's crucial to understand all the migration strategies, and there are several considerations to take into account and questions to answer before deciding which strategy best fits the migration.
Notice that the migration patterns presented in this article are common patterns and should be considered a good starting point for any migration because they cover the basis for many serverless applications.
Serverless Fundamentals
In order to provide more context for the article, let's dig more into the Key advantages of serverless applications, and some common use cases:
What does 'Serverless' exactly means?
No Server Management
Flexible Scaling
Automated high availability
No idle capacity
Top Five use cases for Serverless Computing
Media Processing
Event-Driven Applications
Building APIs
Chatbots
Webhooks
Migration Challenges
While serverless computing has many benefits, it also has some challenges that must be acknowledged or addressed before you can be successful. The purpose of this article is to present them briefly.It's important to understand that those considerations are not only related to Architecture problems, security and compliance are also important topics.
Cold Start Latency: Serverless functions experience a delay when they're invoked for the first time, known as "cold start latency."
Vendor Lock-In: Each Serverless providers offer their unique services and tools Transitioning away from a specific provider can be difficult and costly.
Legacy Systems Integration: Migrate from traditional systems to serverless may be required to integrate with legacy systems. That adds a customization layer with increasing complexity and difficult maintainability.
Resource Limitations: The different Serverless platforms, impose resource limits, such as execution time and memory. In some cases, the limitations are applied to different Regions. High-Scale projects could be affected in terms of performance.
Security Concerns: Ensure the security of data in a serverless environment is a big challenge. Developers must carefully configure security settings and access controls to prevent unauthorized access and data breaches.
Cost Management: Misconfigured functions or excessive usage can lead to unexpected expenses.
Compliance and Data Residency: In regulated industries, can be complex when data is distributed across serverless functions and services.
Monitoring and Debugging: Identifying issues and performance bottlenecks may require specialized tools.
The Migration process
Initial approach
3 preliminary questions should be done prior to accomplishing the migration and decide the strategy:
How is implemented the computing infrastructure?
How is approached application development?
How is approached application deployment?
Answer completely or partially these 3 paradigms is required to decide the strategy. At least all 3 points should be considered and evaluated accordingly.
Infrastructure abstraction
Understand the main infrastructure abstraction and architecture modernization allow us to group the different strategies as well, and can answer part of the questions introduced in the initial approach. For the scope of this project there are 3 abstractions considered :
Server based
Definition:
Also known as a server-centric infrastructure, is an IT architecture where a central server or multiple servers play a crucial role in providing services, managing resources, and storing data for clients or end-users.
Considerations:
monolithic
Single Artifact releases
Usually have some manual deployments
Single Technology stack
Minimal impact moving application to the cloud
Containerized
Definition:
Containers are lightweight, portable, and isolated environments that encapsulate an application and all the libraries, runtime components, and configuration settings it needs to run. This approach offers several advantages in terms of efficiency, scalability, and ease of management
Considerations:
Platform independence
Environment parity
Straightforward deployments
Portability
Security policies of container images and runtime
APIs and microservices
Definition:
APIs and microservices are two interconnected concepts that play a crucial role in modern software development and architecture. They are often used together to build scalable, flexible, and maintainable applications. APIs are sets of rules and protocols that allow one software application or component to interact with another, and the microservices structures the application into those components, being a collection of small, independent services.
Considerations:
Event-driven microservices
CI/CD with polyglot technology stacks
Frequent releases.
Applications need to be rewritten.
Migration patterns
Leapfrog
As the name suggests, with the leapfrog pattern, you bypass interim steps and go straight from an on-premises legacy architecture to a serverless cloud architecture.
Example Scenario: Image Processing
Traditional Setup:
You have a web app that processes images on a dedicated server.
Server maintenance, scaling, and cost management are challenges.
Serverless Migration:
Rewrite the image processing code as a serverless function (e.g., AWS Lambda).
Configure AWS API Gateway to expose an HTTP endpoint that triggers the "UploadImage" Lambda function to S3.
Trigger this function whenever an image is uploaded to an S3 bucket.
Lift and Shift
In this model, existing applications are kept intact initially.
Developers experiment with Serverless tools, like for instance, Cloud functions, in low-risk internal scenarios such as log processing or scheduled tasks. Progressively, other serverless components are adopted for tasks such as data transformations and parallelization of processes.
At a certain stage in the adoption process, it's recommended to take a strategic look at how more serverless and microservices infrastructure might address different business goals.
Then, create a production workload as a pilot, and with initial success and lessons learned in the small processes adopted to serverless previously, more applications could be migrated incrementally to serverless.
Example Scenario: Content Management System (CMS) Migration
Traditional Setup:
You have a traditional CMS running on a virtual server or on-premises infrastructure.
The CMS serves content, manages user accounts, and handles user-generated content.
Lift and Shift Migration to Serverless:
Identify a serverless platform, such as a fully managed cloud service like AWS Amplify or Firebase.
Create a serverless application using this platform.
Replicate the functionality of your existing CMS within this serverless environment.
Migrate your content, user data, and user-generated content to the new serverless application.
Adjust DNS settings or routing to direct traffic to the new serverless application.
Perform testing to ensure the new serverless CMS functions correctly and serves content as expected.
Strangler
With the strangler pattern, an organization incrementally and systematically decomposes monolithic applications by creating APIs and building event-driven components that gradually replace components of the legacy application.
Distinct API endpoints can point to old compared to new components and safe deployment options (such as canary deployments) let you point back to the legacy version with very little risk.
New feature branches can be serverless first, and legacy components can be decommissioned as they are replaced.
Example Scenario: Legacy eCommerce
Traditional Setup:
You have a legacy eCommerce application running on a monolithic server.
It's challenging to maintain and update the old codebase.
Strangler Migration to Serverless:
Start by identifying a specific function, like product image resizing, within the monolithic app.
Rewrite this function as a serverless microservice (e.g., AWS Lambda).
Expose this microservice via an API Gateway endpoint.
Gradually, route new product image resizing requests to the serverless microservice while the rest of the eCommerce app remains on the monolithic server.
Over time, refactor and migrate other functions in a similar manner.
Eventually, the entire application is decomposed into serverless microservices.
Benefits: Incremental modernization, reduced risk, and improved agility without a complete system rewrite.
Top migration questions you need to answer:
Despite the most common migration pattern for moving complex applications is the strangler pattern, where you refactor and rewrite parts of your application with serverless, in many cases, move to serverless coincide with decompose monolith in order to implement Event-Driven microservices.
For the scope of this post, is interesting to give some examples of questions that require to be answered:
What does this application do and how are its components organized?
How does the application scale and what components drive the capacity you need?
Do you have schedule-based tasks?
Do you have workers listening to a queue?
Where can you refactor or enhance functionality without impacting the current implementation?
What is the infrastructure cost/budget to run your workload?
What will be the cost/investment of your team’s time to maintain the application once it is in production.