Serverless and oversimplifications…
Updated: Apr 22, 2020
Serverless architectures are great, and significantly simplify the effort of managing your infrastructure(at a cost). However, we can't be fooled by that simplicity, nor allow our stakeholders to be fooled. Serverless architectures they still require deep technical knowledge and thoughtful consideration. In particular your non-functional requirements are most likely the ones who will make a big difference, so be careful not to fall in the easy trap of oversimplifying or overselling the benefits of serverless architectures.
And now the real thing
Let’s imagine you are the software engineer/architect responsible for designing a new system for a startup; as you are aware of the hype around serverless architectures, you mention it to your stakeholders who immediately get veeeery excited! They know serverless architectures are a trendy topic, so it’s going to look good, appeal to investors and make/save a lot of money!
The basic promise/premise from cloud providers (Azure, AWS, GCP…) is indeed very appealing: give us your application, and we'll run it! You don’t even need to manage any servers or network! :)
What’s not to like? Who cares about the other stuff, about servers, security, scaling, networks, … That stuff tends to be very technical and expensive, and not what product development is really about. So surely serverless is the answer! It will make delivery quicker, right?
So again, what's not to like?
Well, what’s not to like is that most times things aren’t that simple. And if your stakeholders don’t understand what’s actually involved in hosting a system with a serverless architecture, and you don’t articulate the implications to them, things go sideways. And you can’t blame your stakeholder, people naturally get carried away with terms such as “serverless” or even “cloud” and ignore that despite the great value/potential in them, there’s a lot to them. Serverless implementations are seldomly a “plug and play kind of thing”.
So if you are responsible for building/designing a system, and don’t like spending your time answering questions like this:
Can’t we just hire a developer from [YOUR PREFERED FREELANCING PLATFORM] who will get it done?
Why isn’t this live?
When can this be live?
Wasn’t it just a few weeks of development?
Why does it cost so much, why do we need a cloud expert?
then you need to manage your stakeholders properly. Especially those stakeholders who don’t know much about technology, cloud or software engineering. Regardless of how good an engineer you are, if your stakeholders don’t understand what’s at stake, you’ll both be in an uphill battle full of frustrations, lost time and lost money.
The reality is that more often than not, even in serverless architectures, you need multi-disciplinary teams: front-end developers, back-end developers, database experts, QA engineers, Ops engineers, security experts…. Or you need a few of those rare engineers who know it all (and you give them enough time).
But to make my point clear, let me give you an example of how things can be oversimplified. Let's go through one example application inspired on a project I recently worked on. This very basic system consists of:
A small website which collects customer data
A database which stores that same data
A service that runs daily and sends the customer data to an external API.
The overall system, is then, incredibly simple:
As the website development is very small, in a few weeks it’s possible to develop it. The database can be a NoSQL on Cosmos DB (just a couple of collections), and possible to conclude in a few days. In a few weeks, it could easily be up and running, even if built by a very small team of developers.
Let’s see what’s really at stake. Let’s explore 2 basic solutions for hosting this system, both in 100% serverless architectures (I’m going to use Azure to illustrate this example).
Solution 1 – The most basic solution that implements all functional requirements
Angular website to collect customer data, deployed on an Azure App Service
Cosmos DB with a couple of collections
Azure Function that retrieves customer data from the database and sends it to a 3rd party API.
So your Azure resources would be just 4: an App Service Plan, an App Service, a Function App and a Cosmos DB instance.
The problem is that for any professional software engineer, this is manifestly a gross simplification of what should be done, and if done literally as described above will lead to tons of issues.
Solution 2 – A more realistic design
The reality is that most applications must abide by a few non-functional requirements, which can be related to such varied topics such as security, maintainability, scalability and so on. The problem is that most non-technical people when they first think about any piece of software, don’t think about them. Which is why many times they aren’t even written down. But just because no one wrote them, doesn’t mean you don’t have to consider them, right? If a stakeholder asks you to design some system, would you design it in an unsafe way just because the stakeholders didn’t ask explicitly about some security requirement? Of course not! But don’t forget to mention them to your stakeholders, they need to understand why they are relevant, and you need to justify why things take longer, even in a serverless environment.
But going back to our example, let’s look at a design that implements the same functional requirements as Solution 1, but which now takes into considerations realistic non-functional requirements.
So it’s key elements from an application architecture point of view are almost the same:
Angular website deployed on an Azure App Service – Same as Solution 1
Cosmos DB – Same as in Solution 1
REST API – This isolates the code that needs access from the database, promotes reuse and gives independent deployment of API vs Frontend.
Azure Function - Invokes the REST API, and by doing so reuses the customer fetching logic and sends it to a 3rd party API
But your Azure resources for this solution would be:
3 App Service Plan – Isolate each application component (web, REST API and Function), so they don’t compete for the same resources,
2 App Service – Separate app services so you can easily deploy to one without affecting the other,
1 Function App – No change here
1 Cosmos DB instance – No change here, other than whitelisting the App Service for the REST API.
3 instances of Application Insights (for the 2 Azure App Services and 1 for the Function App) – For application monitoring
1 instance of Azure Key Vault (for storing application/database keys that shouldn’t be lying around). This also facilitates the approach of keeping keys out of the CI/CD pipelines and source code repositories.
1 instance of Azure Storage account with at least 1 Azure blob storage – For storing logs
1 Azure Application Gateway - including Public IP, Network Security Group, HTTP(s) Listeners, Backend pools and roles – For routing (and load balancing) traffic to application services without exposing the application services (or any other future resources like VMs), including a Firewall with OWASP support. Ensures all ingress traffic is monitorable. If necessary can also be used to load balance resources within the network.
1 Networks Security Group – To protect the application gateway
1 Virtual Network + Subnet for the Application Gateway – To isolate the network for the application gateway
1 DNS host – To allow the configuration of custom domains for the app services without the need to wait for external registrar configurations.
And you’d also need your Continuous Integration/Continuous Deployment tool of choice to build and deploy your code from your source code repositories into your Azure App Services and Functions.
So comparing both solutions:
* If you have Development, QA, Pre-Prod and production environments you’ll most likely need to multiply several of these resources per number of environments. Alternatively, depending on your App Service Plan size, you could instead choose to use Deployment Slots instead of separate App Service Plans for non-production environments.
** yes…weirdly, this really happens in real life, until recently I never imagined anyone would do this…
In short, be ready to explain to your stakeholders why even in serverless architectures, it isn’t solely a matter of writing code and deploying it to your preferred cloud provider. You also need other resources, a multi-disciplinary knowledge/team, and you can’t just get a freelance developer off a freelancing website. The application code is just a part of it, and stakeholders need to understand that something they conceptualize of needing just a few weeks of work, can in reality much larger.
Part of the problem that leads to this, is that most non-technical stakeholders don’t consider the non-functional requirements (NFRs) of their system (security, scalability, performance, legal, maintainability, etc…), and as such, they think that to get to an application that is live and functional, they just need the functionalities developed. In a serverless architecture, this remains true, but it becomes even more so because the concept of “serverless” insinuates that no infrastructure considerations are necessary.
As such, as your stakeholders will most likely want NFRs to be considered (or some of them), they just haven’t thought about them, the exercise of explaining them is fundamental. Ignoring them only leads to later questions such as “Why does this take so long?” or “is this safe?” or“is this GDPR compliant”?
Without changing functional requirements, a basic solution which only requires 4 Azure Resources to implement, can easily become a solution with 50+ Azure Resources which requires a delivery team with a diverse skillset.
But don’t ignore the key differences between solutions: solution 1 and solution 2 implement very different sets of non-functional attributes and consequently their implementation efforts are quite different. This is why many software architects defend that non-functional requirements (NFRs) are the main drivers of the architecture and that functional requirements are less impacting
But if you can’t explain to your stakeholders why the NFRs matter, then you won’t be able to justify the investment in them. And if you can’t justify it, well, most likely it won’t happen.