In this article, I would like to take you on a journey through the beautiful lands of Azure functions. What are they? How are they useful? Does serverless mean without a server? Does the lightning in the icon somehow correlate to Harry Potter? If you want to get answers to these and many more, keep reading!

Introduction

Before we begin, you should know several essential pieces of information about Azure Functions. First, it’s a serverless solution, and its main selling points are writing less code, maintaining less infrastructure, and increasing cost savings. Here let’s answer one of the questions above: does serverless really mean we are computing in real clouds?

TL;DR: no.
This only means that Azure provides and maintains the infrastructure. There are still real physical servers, and all. They take care of things like scaling, updating all software and OSes, etc. Just like the Thestrals in Harry Potter, they were pulling the carriages. Everyone saw the result of their work. However, only a few could see the creatures themselves, and only a few were working on maintaining them.

Second are some basic terms we have to understand, so let’s take a look alt a small dictionary below.

Understanding basic terms

Function app – an execution context in Azure in which your functions run. It’s a unit of deployment/management for your functions. It consists of one or many functions that are deployed, managed and scaled together. All functions within the function app share the same pricing plan, deployment method and runtime version. It’s a way of organising and collectively managing your functions. Like a kettle where Hogwarts students put their magical ingredients (in this case, functions), they all mix there. They shared the same kettle, had the same temperature (service plan), ended up in the same vial (deployment method), etc.

Develop and test in the browser – you can develop your functions directly in Azure Portal if necessary. However, due to editing functions, this is not a recommended approach. Developing locally and publishing it to a function app in Azure is a better solution.

Imperative development – in short terms, it is about coding first. On the other hand, we have declarative development, which means designer-first. Azure Functions is an example of an imperative development, while f.ex. Logic Apps are declarative.

Triggers and bindings

When learning about Azure Functions, you must understand two things, triggers and bindings. They are among the core ideas behind Azure Functions. Triggers define how your function starts its execution. It can be anything from an HTTP request, an event showing in Event Grid, new input in your DataBase or a message in the queue, after which your function invokes. You can check the complete list here. Each function can have only one trigger.

Bindings, on the other hand, are a way of connecting another resource to a function. We can have either input or output bindings or both. Unlike triggers, bindings are optional; you can mix and match them however needed. For example your function can publish a message to a queue or insert a new input in your SQL database. The full list can be found under the same link above.

Quite like the spells. All spells require triggers with words or thoughts. Some also need an extra input binding of an intention or a happy thought (like the Expecto Patroum). The only difference is that every spell has an output binding. Not perfect, but close enough, I would say!

As you can see, those can be useful when connecting to other services. They help you avoid hardcoding connections. Your function receives data (for example, the content of a queue message) in function parameters. You send data (for example, to create a queue message) by using the function’s return value.

Let’s consider some examples to better understand the concepts. A message arriving in the queue can run the function and send a new message to another queue. In this case, our function has a Queue trigger and one output binding, which is also a Queue.

Another example can be a function that runs every 10 hours, reads Blob Storage, and sends an email. In this case, we have a time trigger, Blob Storage input binding and SendGrid output binding.

Site Icon

NB! From Azure Functions version 2.x runtime only includes HTTP and timer triggers by default.

Hosting options

You can choose one of several available hosting plans for your function app. They define scaling possibilities and mechanisms, available resources for each function app instance, support for Linux containers, and more advanced topics like Azure Virtual Network connectivity. Let’s look at all available plans, the lifetime available and scaling possibilities.

Consumption plan

This is a default compute plan where you pay for what you use, meaning that if your function app is not running, you will not pay anything (pay-as-you-go). It supports automatic scale – instances of your function app are added or removed automatically based on the amount of incoming events.

The default lifetime of a function is 5 minutes, and the maximum is 10. (see more in the Function app timeout section).

Scaling is event-driven and happens automatically, even in high load periods. Infrastructure scales CPU and memory resources by adding more instances based on the number of incoming trigger events. The maximum amount of instances on Windows is 200, and 100 on Linux (during scale-out, there’s currently a limit of 500 instances per subscription per hour for Linux 1. apps on a Consumption plan).

Flex Consumption plan

With this plan, you get everything the Consumption plan offers: extra virtual networking and scalability with computing choices. You can dynamically configure per-instance concurrency and the number of events based on which new app instances will be added or removed. Scaling happens automatically based on the demand.

On top of that, you can define pre-provisioned (always ready) instances to reduce cold starts.

The default lifetime of a function in this plan is 30 minutes, and there is unlimited maximum time.

Flex Consumption plan scaling is still event-driven but more deterministic, as it is calculated per function. We don’t have a restricted number of instances. It is limited only by the total memory usage of all instances in a given region.

Premium plan

The Premium plan offers to scale on demand using pre-warmed workers that run the applications with no downtime after an asleep period. This one offers more powerful instances and connects to virtual network. Good scenarios for this plan are:

  • Your function app has to run (nearly) continously.
  • You want to have more control over your instances and want to deploy multiple function apps on the same plan with event-driven scaling.
  • You are facing a lot of small executions with high execution bill.
  • Your CPU needs are larger than provided in Consumption plans.
  • The execution time is longer than allowed in Consumption plans.
  • Your app requires virtual network connectivity.
  • You want to provide a custom Linux image where your functions will run.

The default lifetime of a function in this plan is 302 minutes, and there is unlimited maximum time.

Scaling is event-driven and scales out automatically based on the number of events that its functions are triggered on. The maximum amount of instances for Windows is 100 and for Linux 10-200 dependently on a region.

Dedicated plan

With a Dedicated plan, you can run a function app in a regular App Service plan with regular App Service plan rates. It’s most suited for long-running scenarios where Durable functions cannot be used. It can come in handy when you have to:

  • have predictable billing or manual scaling of app instances,
  • run mix of web apps and function apps in the same plan,
  • have larger compute size choices,
  • have full compute isolation and secure network access provided by an App Service Environment (ASE),
  • face high memory usage and high scale (ASE)

The default lifetime of a function in this plan is 302 minutes, and there is unlimited maximum time.

Limits for App Service plan scaling apply. We can have max 10-30 instances except for ASE, with up to 100 instances.

Container Apps

You can also create and deploy your function apps with containers in a fully managed environment hosted by Azure Container Apps. In the same way, it can happen in Dedicated or Premium plans. You can have all the benefits of Azure Functions hosted alongside other APIs, microservices, websites and whatever else you might already have in your containers. This can be a way to go for you if f.ex.:

  • you want to package custom libraries together with your code,
  • you want to avoid the overhead and complexity of managing Kubernetes clusters and dedicated compute,
  • there is a requirement of high-end processing power provided by dedicated CPU compute resources for your functions.

The default lifetime of a function in this plan is 305 minutes, and there is unlimited maximum time.

Just like in Consumption or Premium, scaling is an event-driver and happens by modifying the number of instances of the Fonctions host based on the number of events that its function is triggered by. We can have 10-300 instances (we can define the number of instances if there are enough cores on quota available).

Function app timeout

Function pp timeout defines the time after which the function in the function app will go to sleep. It can be set in host.json file with functionTimeout property. This property applies to function execution time. After the trigger starts the function, it must return/respond within the timeout duration. Default timeout value differs between plans and you can see them in the description of every plan.

An HTTP trigger allows a function with an HTTP trigger to respond to a request for a maximum of 230 seconds.

Just like with the spells, again! No spell can live or have a forever effect. It’s just energy that has to end at some point!

That would be all the theory I can think of squeezed into one article. In the next one, we will jump into the code and see what we can do with Functions, how to implement specific triggers, and how to use orchestrators. Stay tuned!