Alex's Coding Blog
  • home
  • about
  • projects
  • contact

Blog

A Journey from WebApi to Azure Functions

  • January 20, 2022
  • by Alexander

Going through achievements for last year, I would like share my introduction to serverless.

I would like to start from the helicopter view: we had a MVP project implemented as a dozen of .NET WebAPI (.net core 3.1). Services are supposed to be resilient and scalable. The initial idea was to have them running on Kubernetes cluster. Sounds nice and simple? It does, in theory... we quickly find out that the system is heavily depends on the platform in this case Kubernetes. Which means, every noise happens in the cluster having direct implication on services its running. These are couple of things to consider next time while choosing orchestration strategy in future:

First, you still will have to manage Kubernetes cluster though it is managed. There is no setup and forget shortcut here, Kubernetes is a complex platform. Even if you are going to spend half an hour a day for monitoring your cluster and checking the alerts, it is still relatively big effort.

Secondly, cloud provider, Azure in our case, forces you to do upgrades of managed Kubernetes from time to time. Yes, you will be notified a couple of months before, but honestly, you can't prepare yourself for unknown. If you did update Kubernetes cluster in production once, you might understand this feeling of uncertainty. You can never know what of your services will run after the upgrade. Not to mention custom cluster's internal services like dns, networking and etc, it can easily become a nightmare.

Thirdly, service meshes are tricky. We introduced istio as a service mesh for the cluster to improve observability, security and monitor internal communication between our services. It is definitely very powerful tool, however we faced a several problems with customization. The reason is that most of these tools still shipped as a beta, which can mean couple of bugs and lack of documentation and community support. It is quite straight forward implemeting the standard use cases, but when implemeting custom things its getting worst. Introduction of such infrastructure tool for you system can only enhance two points mentioned above.

This situation just supported skepticism about the correctness of choice we made for Kubernetes. For intensive system a high availability is major quality attribute. Kubernetes is so complex and so modular system that it takes a quite effort to tune it for specific needs. The effort resources and learning curve we didn't have.

We've decided going for Azure Functions and serverless as a target architecure for several reasons:

  • We don't actually need to monitor and maintain the platform (k8s in our case)
  • We can easily scale up if needed every component separately.
  • With serverless we do not share same platform. Yes, it might be running on same Azure server internally after all, but still its Saas (Function as a service) and not Paas.
  • Simple deployment comparing to container approach - just build and copy files. Which allows us roll out services in minutes regardless region.

Migration to Azure Functions was easy though. We introduced our selfs to a new dotnet-isolated which was super easy to setup. The dotnet isolated mode allows you to enjoy recent .net features were lacking in previous version of Azure functions such as dependency injection. for more about dotnet-isolated refer to this guide.

Here is a several things we had struggled with:

  • Different mind set - at first glance not obvious point. Serverless requires different way of thinking when it comes to structuring your logic specially for long running methods. There are couple of limitation you should be aware of migrating to Azure Functions, execution duration limit and amount connections limit. Best example is a worker that gets data from database, processes it and saves back to the db. No-brainer solution might be wrapping your code in one console app and declaring hosted service that fetches data from database, processes and saves, pr. However, for serverless approach, depending on the load of course, it will not work this way due to duration limitation and maybe connection limitation as well. You will have to split into several functions and maybe with introduction of message queue in the middle: one function gets data from database sends it to processing queue, second function picks up messages for processes and saved them.

  • Bigger Devops effort - considering the above you will probably split your function to several smaller and for each of them CI/CD should be created. The more functions you create, the more devops efforts you need.

  • Shared logic - suppose you have 20 different functions structured in 20 different projects according to Microservices notation. All of them uses same code snippets that you naturally don't want to replicate x 20 times. When you go for shared nuget package, and everything is clean and nice. However, besides obvious advantage this also will have own downsides e.g. every time you improve/fix this shared code you will have to update and redeploy all 20 projects.

  • Learning curve - you will need some time to bring your functions to production ready state polishing middlewares, logging and metrics.

As an outcome I would say I'm rather happy with the choise. However do not consider serverless (microservices) as a "silver bullet" solution for everything. We did found relevant arguments for the migration, so you should.

The End

Azure Architecture .NET Core Azure Functions Serverless

🚀 Turbocharge Your Kubernetes Cluster with my Terraform Kits! 🚀

🌟 Slash deployment time and costs! Discover the ultimate solution for efficient, cost-effective Kubernetes Terraform Kits. Perfect for DevOps enthusiasts looking for a reliable, scalable setup.

Learn More about Terraform Kits for AKS,EKS and GKE

Alexander Lvovich

Solution Architect & Software Developer | Automating & Scaling Infrastructure

💡 Working with Kubernetes, Istio, and DevOps. Got questions? Feel free to reach out!

Share on:

No comments are allowed for this post

Recent Posts

  • Securing Web Services Against Unwanted Traffic with NGINX
  • Optimizing API by Offloading Responsibilities to an API Gateway
  • How to Clean Up Local Branches of Remote Merged Branches
  • Resolving Namespace Overriding in Argo CD with Kustomize
  • Connecting to Gitlab's private Nuget registry
  • Why Istio?

Categories

  • Azure
  • Architecture
  • .NET Core
  • Certification
  • DevOps
  • How-to
  • Azure Functions
  • Serverless
  • Cosmos DB
  • Security
  • Thoughts
  • Kubernetes
  • Istio
© Copyright 2025, Alexander Lvovich. Theme by Colorlib
I use cookies and similar technologies on our website to enhance your browsing experience and analyze website traffic. By clicking "Accept," you consent with my Privacy Policy to the use of these technologies.
Accept