In my last article, I discussed why a development agency would benefit from adopting serverless for their client projects. But if you work in a dev agency, you’re probably now wondering what challenges you can expect to encounter once you take the plunge. Let’s look at a few of the main ones that I’ve noticed when working with dev agencies…
The AWS ecosystem is intimidating
If you’ve used AWS before for building non-serverless workloads, then this won’t be news to you. But if you’re coming to it fresh, then it will take a bit of time for you to understand how its swathe of cloud services fit together.
AWS is a powerful beast and its services are generally best-of-breed (IMHO). But its UX/DX is not always great and it’s not always clear how certain services fit together. In particular, you’ll need to become familiar with areas such as:
- Creating new AWS accounts for each client project
- How IAM (Identity and Access Management) works
Application developers need to get familiar with infrastructure-as-code
IaC has been around for several years now but it’s often seen as a tool for only Systems or Devops Engineers with application developers rarely making use of it. Some don’t even know what it is.
With serverless architectures, this is changing and IaC is becoming a first-class citizen within an application developer’s workflow. Deployment frameworks such as the Serverless Framework and AWS SAM offer an easy on-ramp for developers new to IaC while still providing the flexibility of extending your infrastructure definition using the more complex but extremely powerful CloudFormation.
Your agency’s developers will need to invest the time to learn these tools and avoid the temptation of Console Driven Development. This learning will reap big rewards:
- New client projects that use similar architecture stacks can be very quickly provisioned using templates you created for a previous project.
- Individual developers can use the IaC templates to quickly set up their own personal sandbox environments.
- IaC templates can be used as part of a continuous deployment pipeline, improving the speed and quality of your releases.
Cross-project context switching
Unlike developers in product-based companies, when working in a dev agency, chances are high that you will get called upon to work on multiple projects at once. A bug has been raised by an important client and you’ve been summoned to fix it. It’s higher priority than the fancy new feature you’re currently “in the zone” on for a new client so you need to drop that for now and fix the bug.
We developers hate context switching, but it’s hard to avoid it when your company’s core business is keeping multiple clients happy.
While this issue is not specific to serverless apps, there are a few reasons why I believe it has an over-sized impact on them:
- Standard practices in the serverless space are still emerging. For example, there is no standard way of structuring your codebase or dominant application-level frameworks that make a lot of the decisions for you (akin to Ruby on Rails). This lack of widely accepted practices will increase variance between client projects.
- Serverless apps are inherently distributed systems and as such, tend to have more moving parts than monolithic apps.
So when you open up your old client project in VSCode, it can take a while to familiarise yourself with both the architecture — “how does this asynchronous workflow fit together again?” — and the codebase itself — “is this project still using our own custom rolled module for this feature or had we moved to using the new open source package that solves the same problem?”.
Advanced architectural concepts
In order to get the most out of your cloud service-based architecture in terms of end user experience, performance and system maintainability, there are a few patterns that you should try to adopt when designing your serverless client projects. Here are a few examples of these:
- Prefer asynchronous operations wherever possible. Make heavy use of services such as SNS, SQS and EventBridge.
- Prefer NoSQL databases such as DynamoDB over their SQL counterparts. There is an undoubted learning curve here but they scale better and are significantly easier to integrate with in a serviceful architecture.
None of the above are “must-haves” for building a serverless application, but learning them at an early stage will set you up well for future projects, in particular for client apps that scale up their userbase fast.
Facing down these challenges — a few recommendations
I’m sure there are other challenges facing dev agencies adopting serverless that I’ve forgot to mention but I’ll finish there for now. I’ll leave you with a set of guidelines to help you mitigate the challenges I’ve discussed above, along with some recommended reading on each one:
- Get familiar with core AWS concepts such as IAM and account management
- The ABCs of IAM Permissions by Alex DeBrie.
- Learn Infrastructure-as-Code and use it from day 1
- Use a standard project folder structure to minimise impact of cross-project context switching
- Structuring a Real-World Serverless App by Frank Wang (though I generally prefer starting with just 1 monorepo for the whole system).
- How to end Microservice pain and embrace the Monorepo by Eoin Shanaghy.
- Get familiar with event-driven architecture patterns and the AWS services that you use to implement them
- Serverless Microservice Patterns for AWS by Jeremy Daly.
- If you’re feeling really adventurous, Compare single-table vs multi-table DynamoDB design by yours truly.
And finally, plan for the fact that your first few client projects with serverless will be less productive than with your existing tech stack.
Until next time,