Happy Easter 2024! Let’s celebrate it by diving into Azure functions development. Last time I wrote about configuring a Mongo database in Azure’s Cosmos DB. The next logical step to actually benefiting from your newly configured cloud database is to create code that actually utilizes the database. This code is the logic layer between the database and the user interface. As the user interacts with your data by clicking on menus and links in the UI, ideally the UI converts these actions to requests to your API. Your API in turn is the layer that interacts with the database and returns data snippets based on these requests.

An increasingly popular way to implement these kinds of APIs is through “serverless functions.” It’s a paradigm that allows you to create simplistic business logic snippets and directly deploy them to the cloud. The idea behind this is that the cloud service, such as Amazon AWS or Microsoft Azure then takes care of the “boring” infrastructure required to keep your “functions” up and ticking by providing them with automatic scaling based on the actual traffic load. So let’s get practical and get started with Azure functions!

Getting Started

A good starting point for Azure functions development on Visual Studio Code is to install Microsoft’s Azure tools extension.

the-cosmos

From there, I recommend to proceed to installing Azure functions core tools, which is quite easy. On Ubuntu Linux operating system it just requires to copy paste four commands.

Firstly, add the Microsoft repository GPG key:

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg

Then, update your sources list:

sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -cs)-prod $(lsb_release -cs) main" > /etc/apt/sources.list.d/dotnetdev.list'

Update your APT source:

sudo apt-get update

Finally, install the core tools package:

sudo apt-get install azure-functions-core-tools-4

Check out also the comprehensive Microsoft’s tutorial to Azure functions local development here.

install-azure-functions-core-tools

Creating Your Business App in the Cloud

After completing the above mentioned configuration rituals on your workstation, you are ready to take your next big step and actually set up the business system of the new enterpise in Azure cloud.

In essence, it is a really simple two-step process:

  1. Click “Create Function App” in Azure Portal
  2. Fill the form

After these steps are completed, we are ready to start building and deploying improvements and updates to our new business system as a continuous flow of little steps! In its purest essence, every software, like every business, is just like clay, and the art of crafting software is like pottery. You can make any kind of pot you want from wet clay!

creating-function-app

Greatness of Scripting

Now, configuring resources on a web portal by clicking on menus and links, this is something called “manual work” these days. It isn’t always immediately clear to any impatient Kalabaw entrepreneur that this kind of manual work is actually risky business. Namely, if you do all configurations to your business this way, it may appear the simplest way in the beginning. But in the long term it often turns into headache, when the number of configured objects in the cloud grows and you need to do refactoring that alter multiple places. Therefore it is crucial that the infrastructure can be fully scripted. Then you can even fully delete, clone and rebuild everything without worries, any time. So let’s delete the store app that we just created:

 az functionapp delete --name KalabawFoods --resource-group foodStoreRG

And after this, recreate the app from scratch, with a script!

# Variable block

appname="kalabawfoods"
location="eastus"
resourceGroup="$appname-azure-functions-rg"
tag="create-function-app-consumption"
storage="storage$appname"
functionApp="$appname-serverless-function"
skuStorage="Standard_LRS"
functionsVersion="4"

# Create a resource group
echo "Creating $resourceGroup in "$location"..."
az group create --name $resourceGroup --location "$location" --tags $tag

# Create an Azure storage account in the resource group.
echo "Creating $storage"
az storage account create --name $storage --location "$location" \
    --resource-group $resourceGroup --sku $skuStorage

# Create a serverless function app in the resource group.
echo "Creating $functionApp"
az functionapp create --name $functionApp --storage-account $storage \
    --consumption-plan-location "$location" --resource-group $resourceGroup \
    --functions-version $functionsVersion

function-app-script

Doing Some Real Business Functions

Now let’s find out how to take advantage of Azure Core Tools that we just installed. It is a good point so start writing some real scalable business functions to support our emerging food business.

Let’s make a project to locally develop those functions on your workstation:

func init KalabawFoodsFunctions --worker-runtime dotnet-isolated

Our imaginary food entrepreneur cannot just wait getting real and implement a business function that can return a product list to the web app. After all, the product is the core of every successfull business. So let’s create a Products function:

 cd KalabawFoodsFunctions
 func new --template "Http Trigger" --name Products

This generates the initial implementation of the Products function. Its job is going to be returning accurate listing of food store’s available products. Later the entrepreneur wants to configure the function to query Cosmos DB and return results from there. But at this point he just wants to write the simplest possible iteration. So let’s update the the generated function and hard code the initial product list to contain the store’s core foods:

Canned Kalabaw liver, Bahay Kubo sausage, Horn powder

and placing this product data into the actual function’s code, we get:

using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace KalabawFoodsFunctions
{
    public class Products
    {
        private readonly ILogger _logger;

        public Products(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<Products>();
        }

        [Function("Products")]
        public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            var response = req.CreateResponse(HttpStatusCode.OK);
            response.Headers.Add("Content-Type", "text/plain; charset=utf-8");

            response.WriteString("Canned Kalabaw liver, Bahay Kubo sausage, Horn powder");

            return response;
        }
    }
}

Deploying the function

Verify that the function builds:

dotnet build

Run it locally:

func start

And finally, depoly it:

func azure functionapp publish kalabawfoods-serverless-function

To learn more about developing Azure functions with core tools, have a look at this tutorial.

From Functions to Container Apps

Serverless functions, such as Microsoft’s Azure Functions or even Amazon AWS Lambdas, are suitable for making your web services scale up to sudden visitor spikes. However, they aren’t that suited to constant heavy weight background processes, such as doing continuous conversion of a steady measurement data flow from multiple instruments into other data format that serves certain user interfaces. Typically the data flow from hardware instruments, although sometimes big, is also quite predictable - huge spikes are not expected since the number of hardware grows in a rather managed way. So clearly architectures based on Kubernetes containers serve a business case entirely different from a lambda scenario.

There is a definite answer to the long-lasting debatte about Kubernetes containers vs serverless functions. And the answer is Container apps! These beasts combine the best from the both worlds. They have all the flexibility and power that traditional Kubernetes based containers have (and serverless functions don’t have) and yet they provide the same automatic scalability to handle load spikes, without cold start issues, timeouts, memory problems and the like. On AWS planet, Container apps would roughly translate to Amazon ECS & Fargate. Kuberenetes is still relevant. What we see is just Kubernetes containers evolving to apps with automated scaling for the containers. These we call containerized apps.

Coming soon…

Let’s check out how to kick up some serious function container apps. Cheers!