# Challenge 2: Serverless

⏲️ Est. time to complete: 45 min. ⏲️

# Here is what you will learn 🎯

  • Create an Azure Function on your local machine
  • Learn how to debug Azure Functions
  • Learn how to use Function Triggers to react to events in Azure
  • Deploy Azure Functions

# Table Of Contents

  1. Create an Azure Function locally
  2. Deploy the Azure Function App to Azure
  3. Azure Samples
  4. Cleanup

# Create an Azure Function locally

To get familiar with Azure Functions on your local machine, we will create a sample that listens for files on an Azure Storage Account (Blob). Each time a new file is added to a predefined container, our function will be called by Azure, giving us the opportunity to manipulate the file and save it to another location (just a small sample).

So, first of all, we need to create a Storage Account to being able to upload/process files.

# Add a Storage Account

Go to the Azure Portal and click on "Create a resource", in the next view choose/search for "Storage Account" and afterwards click create.

Follow the wizard to create the storage account:

Parameter Value
Resource group new, serverless-rg
Name Give your account a globally unique name
Location West Europe
Performance Tier Standard
Account Kind Storage V2 (General Purpose)
Replication Locally-redundant storage (LRS)
Access Tier Hot

Leave all other options to their defaults. In the summary view, it should look like that:

create

Proceed and create the Storage Account.

When the deployment has finished

  • Go to the storage account and open "Containers" (under "Blob service")
  • Create a container called originals and another one called processed
  • Leave the proposed settings for Public Access Level - Private.

The infrastructure to store files is now ready. Let's create the local Azure Function.

# Create the local Function App

Open a new Visual Studio Code window and switch to the Azure Tools Extension. In the section for "Functions", click on "Create New Project" and select a new, empty folder on your local machine:

func_create

The Wizard will guide you through the local setup process.

Choose the following options:

  • Language: C# functions_wizard1
  • Template: BlobTrigger functions_wizard2
  • Function Name: BlobTriggerCSharp functions_wizard3
  • Namespace: AzDevCollege.Function functions_wizard4
  • Settings: Create new local app setting functions_wizard5
  • Storage Account: select the storage account you created previously functions_wizard6
  • Trigger Path (the container name we want to listen to for new files): originals functions_wizard7
  • Debug: select the same storage account as above

When everything is setup, we test the function.

  • Open BlobTriggerCSharp.cs file and set a breakpoint in the Run method.
  • Start the Azure Function by hitting F5.

TIP

📝 If you get a message that the core function tools are required, install them by executing npm i -g azure-functions-core-tools@3 --unsafe-perm true. If you still see an error, it's likely that remote-signed Powershell scripts aren't allowed on your machine. To fix that, run Set-ExecutionPolicy -ExecutionPolicy RemoteSigned in a Powershell environment (as admin).

The debug console should print logs like that:

> func start

Azure Functions Core Tools
Core Tools Version:       3.0.3284 Commit hash: 98bc25e668274edd175a1647fe5a9bc4ffb6887d
Function Runtime Version: 3.0.15371.0

Open the Azure Storage Explorer, find your storage account and select the originals container (alternatively: go to the Portal and open the "Storage Explorer" in the Storage Account).

storage_explorer_view

Drag and drop a file to the container or upload one via the menu. After a few seconds, the breakpoint in VS Code will be hit. Examine the properties of the variable myBlob.

# Adjusting the Sample

We can now receive events when a file is added to blob storage. Let's add a more meaningful sample.

We want to receive images that we will resize/manipulate in our function and write the result to the processed container. Therefore, we need to add a dependency to our project that enables us to do image manipulation in dotnet core. We will use SixLabors.ImageSharp (opens new window).

Open a terminal and go to your projects folder. Add the library via:

dotnet add <NAME_OF_FUNCTION_PROJECT>.csproj package SixLabors.ImageSharp

Now, back in Visual Studio Code, replace the contents of the file BlobTriggerCSharp.cs with:

using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

namespace AzDevCollege.Function
{
    public static class BlobTriggerCSharp
    {
        [FunctionName(nameof(BlobTriggerCSharp))]
        public static void Run(
            [BlobTrigger("originals/{name}", Connection = "<REPLACE_WITH_NAME_OF_STORAGE_ACCOUNT>_STORAGE")]Stream myBlob, string name,
            [Blob("processed/proc_{name}", FileAccess.Write, Connection = "<REPLACE_WITH_NAME_OF_STORAGE_ACCOUNT>_STORAGE")] Stream outStream, ILogger log)
        {
            using (Image image = Image.Load(myBlob))
            {
                // Resize and rotate the image!
                image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2));
                image.Mutate(x => x.Rotate(90));

                image.SaveAsJpeg(outStream);
            }
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
        }
    }
}

What has been added to the Run method:

Now restart the local Azure Function and when the function is ready to accept calls, go to the Storage Explorer and drag an image (!use an image!) to the folder originals. A few seconds later, you will see that the Azure Function has been triggered.

Now check the processed container. You will find a new proc\_-image with the results of our manipulation.

If everything works as expected on your local machine, we deploy the Azure Function to Azure.

# Deploy the Azure Function App to Azure

Go to the Azure Tools Extension and click on the "Deploy to Azure..." button in the "Functions" section. A wizard will guide you through the creation process.

TIP

📝 Choose Advanced mode.

functions_deploy_wizard1

Choose the following options, when asked:

Parameter Value
Runtime NET Core 3.1
OS Windows
Hosting Plan Consumption
Resource Group serverless-rg
Storage Account The same as you used in the local sample
Application Insights Skip for now

We still have to configure our Functions App, to be able to listen to blob changes in the Storage Account (BlobTrigger information). Therefore

  • Go to the Portal and open the Functions App you previously created.
  • Open the Application settings under Configuration
  • Add a new application setting (you can check your local.settings.json file for the correct values):
    Parameter Value
    <storageaccountname>_STORAGE enter the connection string to the storage account (you can copy that from your local.settings.json file)

TIP

📝 Make sure to click on Save afterwards.

Finally, your application settings should look like that:

azure_function_settings

Test again (upload images) and check, if the Function App is running correctly in Azure

TIP

📝 It might be necessary to restart your function app.

# Azure Samples

Azure Functions code samples:

# Cleanup

Remove the sample resource group via

az group delete -n serverless-rg

◀ Previous challenge | 🔼 Day 2 | Next challenge ▶