Porting to serverless
Originally published at www.stackery.io.
Unless you have the luxury of building your application from scratch, chances are you’ll face a point where you’ll have to decide on a strategy for migrating your application to a serverless/functions-as-a-service (FaaS) architecture. While some considerations, like support for your application’s language and runtime version, are fairly straightforward, your overall strategy will probably depend on a number of factors including your application’s maturity, architecture, and framework.
Service Oriented Architectures
If you’ve already servicified your application, including decoupling independent functionality, you’re likely in a good position to begin a serverless migration. Typically, you’ll identify a relatively low-risk service to migrate and build confidence and experience with your new FaaS infrastructure. Good candidates for testing serverless architectures are background task queues and internal analytics services which store data for retrieval at a later time.
While this is a relatively simple starting point, you may need to put some consideration into how your service will handle state and how service discovery will work within your distributed system. As you build success with individual services, the task of bringing over the entirety of the application should get easier.
If your application is predominately an API, you’re in luck — FaaS architecture is well-suited to API use cases. You have at least two reasonable paths forward for an API migration: decompose your API to individual functions or port your API framework.
Decomposing your API is easy enough; define your routes and connect them to individual functions. This works well if your functions are reasonably transactional and don’t require much interdependency, but it can also be time consuming to break apart your application in this way and increases the complexity of deploying and updating your API.
Alternatively, depending on your API framework, it may be possible to load the entire API into a single AWS Lambda function, like we did with the Hapi framework. This technique is often easier to maintain and deploy, but does require a bit of handler logic to parse your API request.
Monolithic and Legacy Applications
If your goal is to bring a legacy or monolithic application to a FaaS provider, you’re likely in for a bit of a challenge. While it may be theoretically possible to load certain applications in Lambda, it’s likely that the resource requirements, cold boot times, and architectural differences of FaaS infrastructure will make this approach all but impossible.
This could be your opportunity to start to break apart your application into a service oriented architecture. This, of course, takes some effort and planning but brings all of the SOA benefits of increased maintainability, decreased developer ramp-up time, and service reusability. As you break services out of your monolith you can build them onto serverless architecture natively.
On the other hand, if servicification of your application is untenable for any number of reasons, you may find significant benefits in a hybrid infrastructure approach. Using services like AWS ECS or Kubernetes can allow you to run cloud-native applications with higher infrastructure utilization rates, and can help to consolidate your operations and infrastructure strategy across both containers and FaaS.
There are a number of pragmatic paths to migrating your applications onto serverless infrastructure. Each come with their own considerations, limitations, and with various levels of effort. Organizations making this switch often find that their applications become easier to maintain, quicker to update, and have significantly better infrastructure cost models. In general, the transition is easier than you might expect and gets faster after a little initial experience.