Deep dive into Azure Functions

Let’s explore the power of Azure Functions and Durable Functions to build scalable and reliable event-driven applications!

Raghav Gupta
Simform Engineering
12 min readMay 1, 2023

--

You must have requirements like automating business processes, processing data in real-time, integrating with third-party services, etc. And Azure Functions has got you covered! By using Durable Functions, you can easily orchestrate these functions and create complex workflows with reliable state management.

Throughout this article, we will dive into creating durable functions, managing states, and monitoring function execution. We will also look into the powerful serverless compute platform of Azure Functions and explore its many capabilities. We will specifically focus on leveraging the Durable Functions extension to create stateful workflows and function chains.

By the end of the post, you will have a comprehensive understanding of how to use Azure Functions and Durable Functions to build powerful and scalable serverless components of your application.

What is it?

Azure Functions is a cloud-based service provided by Microsoft Azure that enables users to run serverless applications or functions. It allows developers to build and run small pieces of code that can be triggered by various events such as HTTP requests, database changes, or even a scheduled timer.

Azure Functions is designed to simplify the development process by abstracting the infrastructure and enabling developers to focus on writing code. It also supports multiple programming languages such as C#, Java, JavaScript, Python, and PowerShell. This makes it possible for developers to use their preferred language and tooling to develop and deploy their applications.

Features of Azure Functions

  • Serverless service: Developers do not have to manage the underlying infrastructure, such as servers or operating systems.
  • Scalability: It provides automatic scaling based on demand and consumption, which makes it highly scalable.
  • Integration with Other Azure Services: Azure Functions integrates with other Azure services such as Azure Event Grid, Azure Blob Storage, and Azure Cosmos DB. This makes it easier to create complex applications by integrating different services without having to write custom code for each service.
  • Cost-effective: You can spin up an Azure function almost for free in the consumption plan which gives 1 million requests!
  • Monitoring and Logging: Azure Functions provides detailed logging and monitoring capabilities, including real-time metrics and alerts. For instance, Azure Application Insights provides the monitoring of Azure Functions.
  • Debugging: It supports local and remote debugging, making it easier to identify and fix issues.
  • Event-driven Programming — Functions can be triggered by various events, which makes it easier to build reactive applications that respond to changes in real-time.
  • Easy Deployment: Azure Functions provides various deployment options to deploy and manage the functions, such as Azure Portal, Azure CLI, Visual Studio, GitHub, and Docker Containers.
  • Serverless Orchestrations: Azure function provides an extension called Durable Functions which allows executing complex business workflows in a serverless manner.

Applications of Azure Functions

  • Reminders and notifications: Send emails, SMS messages, push notifications, or alerts based on events or schedules.
  • Scheduled tasks: Run background tasks at regular intervals or specific times, such as cleaning up databases, processing logs, or generating reports.
  • Lightweight Web API: Create simple RESTful services that can handle HTTP requests and responses.
  • Sending background emails: Send emails asynchronously after a user action, such as signing up, placing an order, or submitting feedback.
  • Running background backup tasks: Backup data from one storage account to another, or from one cloud provider to another.
  • Generating reports: Generate reports in the background based on different triggers, such as time, file upload, or data change.
  • Data processing: Collect and process data from loT devices.

Azure Functions Pricing

Azure Functions pricing model offers flexible options based on the consumption of resources used by the function app.

There are three pricing plans:

  1. Consumption Plan: It is a serverless pricing model where you only pay for the execution time of your functions. This plan provides free grants of 1 million requests and 400,000 GB of resource consumption per month per subscription. There are no upfront costs or reservation requirements for this plan.
  2. Premium Plan: It is a dedicated hosting plan that provides more powerful compute resources and higher scalability limits. This plan is ideal for applications that require high performance and low latency. The Premium Plan offers a minimum of 1 vCPU and up to 14 GB of memory. You can also scale up to 1000 vCPUs and 14 GB of memory per instance. It also provides advanced features such as Virtual Network Integration, enhanced monitoring, and scaling controls.
  3. Dedicated Plan: It allows you to have a dedicated instance of Azure Functions running on either Windows or Linux, and you have complete control over the resources allocated to that instance. You can choose the number of vCPUs, amount of memory, and storage capacity, as well as configure networking, security, and monitoring settings. The Dedicated Plan also provides advanced features such as integration with Virtual Network, Hybrid Connections, and Application Insights, as well as support for custom domains and SSL certificates. However, you need an App Service plan in place to work with a Dedicated plan.

Create your first Azure Function App

  1. Create a Resource Group.

2. Create a Storage Account.

3. Create a Function App.

4. From Visual Studio, create a project with “Azure Functions” template.

5. Choose Http Trigger Function and Anonymous authorization type.

Once you create, the default template looks like this:

The above code returns a string based on the parameter we send through HTTP GET or POST request. Function1 defines the name of a function, and it can be accessed using /api/Function1. AuthorizationLevel is defined as Anonymous which means this endpoint has public access.

Finally, create a publish profile and publish to our new Azure Function App newFunction

Visit the Azure portal, under the resource group, you can now see a new function the Azure Function App with Function1 function in place. From there you get a URL with which you can trigger the Function.

Authorization in Azure Functions

There are two types of keys with which Azure Functions performs the authorization:

  1. Host Key is a security key used for administrative access to the Function App. From the portal you get the host key from Function App resource > Access Keys > Host Keys

2. Function key is a security key used for access to a specific Azure Function within the Function App. From the portal you get function keys under function > Function Keys

Based on both keys, Azure Functions has below Authorization techniques for HTTP Trigger:

  1. Anonymous: No API key is required. Anyone can access the function without any authentication.
  2. Function: A function-specific API key is required. You can use either a function key or a host key to access the function.
  3. Admin: A host API key is required. Only a host key can access the function.

Publish Azure function as a Docker container

Publishing an Azure Function as a Docker container provides a flexible and efficient way to package and deploy the function, while also improving consistency, scalability, and resource utilization.

You can publish your Azure Function as a Docker container by following these steps:

  1. In the above project, add a docker support.

2. Create a new Publish profile with below options.

3. It will ask to create a new Azure Container Registry. Once it is created, you can publish the dockerized function.

Types of Triggers in Azure Functions

Azure Functions supports several types of triggers, including:

  • HTTP Trigger: It allows you to execute your function in response to an HTTP request. You can use this trigger to build web API and other HTTP-based services.
  • Timer Trigger: It allows you to execute your function on a schedule, such as every minute, hour, or day. You can use this trigger to implement background tasks and scheduled jobs.
  • Cosmos DB Trigger: It allows you to execute your function in response to changes in a Cosmos DB collection. You can use this trigger to build real-time applications that react to updates in the database.
  • Blob Trigger: It allows you to execute your function in response to changes in a storage blob container. You can use this trigger to process new or updated files in the container.
  • Event Grid Trigger: It allows you to execute your function in response to events from Azure services, such as Blob storage, Event Hubs, and Custom topics. You can use this trigger to build event-driven architectures.
  • Service Bus Trigger: It allows you to execute your function in response to messages in a Service Bus queue or topic. You can use this trigger to build messaging-based applications.
  • Queue Trigger: It allows you to execute your function in response to messages in an Azure Storage queue. You can use this trigger to build queue-based applications.
  • Event Hub Trigger: It allows you to execute your function in response to events from an Azure Event Hub. You can use this trigger to build real-time event-processing applications.

Durable Functions

Durable Functions is a framework built on top of Azure Functions that provides a set of triggers and actions for building stateful workflows.

You can use this framework to build complex, long-running, stateful processes composed of multiple steps and multiple functions. To enable this, Azure Durable Functions provide four types of functions:

  1. The OrchestrationTrigger function is responsible for defining the workflow and managing its state. It is triggered by external events, such as an HTTP request or a queue message, and can call other functions as needed. This function has a special context object that allows it to manage the state of the workflow and control the execution of other functions. Client function can interact with the Orchestration function in the following manner:
  • start the orchestration
  • query their status
  • terminate
  • send events to them while they’re running
  • purge instance history

2. The ActivityTrigger function performs a specific task as part of the workflow. It is called by the OrchestrationTrigger function and can return a result, which is then passed back to the OrchestrationTrigger function. These functions should be stateless and idempotent, meaning they can be called multiple times without changing the outcome. Activity functions are the basic unit of work in durable function orchestration. They are frequently used to make network calls or run CPU-intensive operations.

3. The EntityTrigger function manages the state of a Durable Entity, which is a persistent stateful object that multiple functions can access and modify. The EntityTrigger function is triggered by changes to the state of the Durable Entity and can update the entity state or perform other actions in response to the change.

4. The Client function enables external clients, such as web applications, to interact with a running Durable Function workflow. Client functions allow developers to start and monitor workflows, send input to the workflow, and receive output from the workflow.

Durable function Patterns

Azure Durable Functions provide several patterns that developers can use to build complex, long-running workflows. Here are a few most common patterns.

1. Function Chaining

It refers to the pattern of executing a sequence of functions in a particular order. The output of one function is input to another. You can also implement control flow using if-else and loops.

You can use context parameter to invoke other functions by name, and pass parameters, and then return function output. And each time the code calls await, the Durable Functions framework checks the progress of the current function instance.

Call the “Chaining” Durable Orchestrator from HttpTrigger. Once you run the solution, you will get Uri to invoke the “Chaining” orchestrator:

You need Azure Storage Account in place to run Functions in Azure. In local environment, Azure Storage Emulator is used which enables us to run code locally. Durable functions internally use Aure Blobs, Queue, and Tables. You can check that in Azure Storage Explorer:

2. Fan-out/Fan-in

In this pattern, you execute multiple functions in parallel, and then you wait for all functions to finish. Fan-in includes some aggregation work on the results returned from the functions. With normal functions, you fan out by making the function send multiple messages to a queue. To fan-in in a normal function, write code to track when queue-triggered functions end and then store function outputs.

The fan-out work is distributed to multiple instances of the function F2. And the work is tracked using a dynamic list of tasks. Task.WhenAll is called to wait for all the called functions to finish. Then, the F2 outputs are aggregated from the dynamic task list and passed to F3 function.

3. Async HTTP APIs

This pattern addresses the problem of coordinating the state of long-running operations with external clients for example — file upload.

Durable Functions runtime has a built-in status-tracking mechanism. It will provide an endpoint with which you can check the status of long-running process. When the long-running process is executing, the endpoint will return the 202 accepted status; and when execution is completed successfully, it will return 200 OK.

Here are the two endpoints:

  1. /api/orchestrators/DoWork — A long-running process, which will return 202 Accepted right away with a URL (2nd endpoint).
  2. /runtime/webhooks/durabletask/instances/{id} — It will return the status of a long-running process.

4. Monitor

The monitor pattern has been designed to automatize the process of status checking. In contrast with the Async HTTP APIs pattern, the client does not need to check the status of the orchestrator execution.

Below is the code and explanation of Monitor patterns.

Monitor orchestration function will poll a long-running process GetJobStatus at a regular interval until expiration time is reached or a condition is met (jobStatus == "Completed").

You can define an activity function (SendAlert) invoked after completion and perform some action to inform the user. For example, you can use SendGrid to send an email or Twilio SMS service to send an SMS.

You can expose the webhook HTTP API to check the status of your monitor and terminate the execution if needed.

5. Human Interaction

Various automated processes involve some kind of human interaction. Durable Functions provides these automated processes which allow for such interaction by using timeouts and compensation logic. You can implement the pattern by using an orchestrator function.

Below is the code for human Interaction:

context.CreateTimer — The orchestrator uses a durable timer to request approval.

Context.WaitForExternalEvent — The orchestrator waits for an external event, such as a notification that’s generated by human interactions.

Task.WhenAny — Here orchestrator decides whether to process or escalate.

Aggregator (stateful entities)

This pattern is about aggregating event data over a period of time into a single, addressable entity.

In this pattern, the data being aggregated may come from multiple sources, and may be delivered in batches or scattered over a long period of time. The aggregator may need to take action on event data as it arrives. And external clients may need to query the aggregated data.

Here, the Durable function helps in maintaining concurrency control which curbs multiple threads from modifying the same data at the same time.

Wrapping up 👏

I hope you enjoyed the deep dive into the world of Azure Functions. Whether you’re a developer, a business owner, or a technology enthusiast, this service can help you streamline your workflows and achieve your goals with greater ease.

You can find the working code in this repo: https://github.com/raghav18gupta/azure-functions

For more such insights and updates on the latest tools and technologies — follow the Simform engineering blog or visit the Simform website.

--

--