First Steps with Azure Functions

What does serverless mean in Azure? Follow Giuseppe Battista’s first steps with Azure Functions and discover the shortest path from Code to Cloud.

Here at Cloudreach, we love stepping out of our comfort zone and exploring different, exciting technologies.

I am a seasoned software developer with a passion for everything serverless In the last few years my focus has been AWS and Node.js but lately, I have decided to explore the interpretation of serverless in the Microsoft world.

In this article, I want to go through my first experience with Azure Functions. I’ll first create a Windows development machine with Visual Studio in Azure, then use the IDE to build and, finally, publish my first Azure Function.

Setup

One of the things I love about the Cloud is how easy and frictionless it is to run experiments. In this context, I decided I didn’t want to install and run an IDE on my workstation but rather use a pre-configured virtual machine in the Cloud and connect to it via Remote Desktop. This has many advantages. I can have a reproducible, isolated development environment, I don’t have to spend time installing and configuring my workstation and I can easily access more computational power, should I needed it.

IDE

I’m going to use Microsoft Visual Studio 2019 Community Edition on Windows Server 2016. Here is how to set it up in Azure:

  • Log to Azure Portal with your subscription details. If you don’t have a subscription, follow these instructions to get started with Azure for free.
  • In the main search bar, type “virtual machines” then tap on the first result.

Tap on '+ Add' to create a new Virtual Machine. Fill in the form as shown in the following figures:

Choose a 'Resource group' from the dropdown, or create a new one by tapping on 'Create new'.

The right 'Image' can be found by tapping on 'Browse all public and private images' and searching for Visual Studio 2019, as shown in the following figure.

Setup an administrator user and take note of your username and password.

Leave the default values for all other options on this page. Tap 'Review + create.'

Review the configuration, then tap on 'Create'.

If the deployment is successful, the following message should be displayed:

Enabling Remote Desktop

Before jumping onto coding, follow the next steps to enable RDP (Remote Desktop Protocol) connectivity from your workstation to your remote development machine. 

  • Log to Azure Portal, search for “virtual machines” in the main search bar
  • Tap on 'azure-ide'
  • On the menu on the left search for Networking and inspect the networking rules.

  • Take note of 'NIC Public IP' in order to connect to your Remote Desktop later. This is the IP that has been assigned to your machine in the Cloud.
  • Tap on 'Add inbound' and complete the form as in the following figure. Get your IP here. Adding this rule allows your remote development machine to accept traffic from your IP only through the port 3389.

Connect to your remote development machine

You can connect to your remote development machine by using a Remote Desktop Client. Follow these instructions to get started on Windows, MacOS and Linux.

Open up your Remote Desktop Client (for example, I am using Microsoft Remote Desktop), enter your 'NIC Public IP' and your administrator credentials. In a few seconds, you should be able to see Windows starting up and finally your Desktop.

Build the Function

Once you’re logged onto your remote development machine, open up Visual Studio by clicking on the icon on your desktop and select 'Create a new project'

From the list of available projects, select 'Azure Functions'. Tap on 'Next'.

Name your function as shown in the figure and select a path on your disk to host the code. 

Select 'Http trigger', set Storage Emulator as your 'Storage Account', finally select 'Anonymous' as Authorization level.

Test the Function Locally

Visual Studio will generate a project from a template with boilerplate C# code for your function. To build and test the function, tap on the highlighted button in the figure below.

Visual Studio will compile and run your function locally. Take note of the URL for Function1, highlighted in the following figure.

Make sure your function is up and running by opening up a PowerShell window: click on Start and search for PowerShell as shown in the following figure.

Issue the following command to invoke the locally running Function.

curl http://localhost:7071/api/Function1?name=azure

Please note that your URL might differ.

In Visual Studio console, you should see the logs of your request. Make sure that in both logs you receive a status of 200.

Publish the Function to Azure

Out of the box, Visual Studio makes it easy to publish your function to Azure. From the Build menu, select 'Publish AzureSampleFunction', as shown in the picture.

Select 'Azure Function App' as your target, click on 'Create New' and make sure 'Run from package' file is checked. Click on 'Publish'.

You need to sign in to your Azure account: click on 'Sign In' and enter your account credentials.

 

Upon successful login, enter a name for your function, select your 'Azure Subscription', choose or create a new 'Resource Group', 'Hosting Plan' and 'Azure Storage bucket'. Click on 'Create'.

Visual Studio will package and publish your code to Azure Functions. When the process completes, take note of the Site URL. This is the URL your function has been deployed to.

Test the Function on the Cloud

Open up a PowerShell prompt and issue the following command to test your function deployed in the Cloud.

curl https://<SITE-URL>/api/Function1?name=azure

You should receive a response similar to the following.

If you get 200 OK response, your function is up and running in Azure!

The Code

Let’s try to make sense of the code: the first few lines are all about importing dependencies.

 

using System;

using System.IO;

using System.Threading.Tasks;

using Microsoft.AspNetCore.Mvc;

using Microsoft.Azure.WebJobs;

using Microsoft.Azure.WebJobs.Extensions.Http;

using Microsoft.AspNetCore.Http;

using Microsoft.Extensions.Logging;

using Newtonsoft.Json;

 

Whenever your function is invoked (in this case by an HTTP request), Azure will run the public static method Run of the public static class Function1, defined in the namespace AzureSampleFunction. As stated in the method signature, Run is a public static asynchronous method that accepts an HttpRequest object and an ILogger object as parameters and returns a Task of IActionResult. The HttpRequest object includes all of the properties of the triggering HTTP request, while the ILogger is the object used to log information about the execution of the function, for debugging and auditing purposes.

 

namespace AzureSampleFunction

{

    public static class Function1

    {

        [FunctionName("Function1")]

        public static async Task<IActionResult> Run(

            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,

            ILogger log)

        {

            log.LogInformation("C# HTTP trigger function processed a request.");

 

Leaving the implementation details to the side, the goal of this function is simple:

  • Make sure that the HTTP request body or query string includes a property called name and that such property has a value
  • If the previous condition is met, reply successfully with a customized greeting
  • otherwise, inform the users that their request is invalid and provide instructions to fix it.

This workflow is expressed in the following lines.

 

            string name = req.Query["name"];


            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            dynamic data = JsonConvert.DeserializeObject(requestBody);

            name = name ?? data?.name;


            return name != null

                ? (ActionResult)new OkObjectResult($"Hello, {name}")

                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");

        }

    }

}

Clean up

The best selling point of the Cloud is probably its elasticity: if you need more resources you can draw from a virtually infinite pool and when you’re done, you can just release them. This brings two advantages: the ability to scale up on demand and fine-grained cost control.

When you’re done with your IDE you can shut it down and get rid of it.

Log to Azure Portal and search for “virtual machines” in the main search bar. Select your development machine ('azure-ide') from the list of available virtual machines, then tap on 'Stop'. Once the machine is shut down, tap on 'Delete', as shown in the figure.

Main Takeaways

Being new to Azure and Visual Studio, I am impressed with the degree of integration offered by the IDE: in just a few clicks I was able to build, test and publish my function. 

The development experience is in many regards similar to the one I had with AWS and Cloud9, of course with a Microsoft flavor to it and native support to .NET.

I found C# excessively verbose compared to other languages I am more familiar with (Javascript, Python or even Go), but that might just boil down to personal preference.

Finally, Azure Function Tools (a local testing environment for Azure Functions provided by Visual Studio) is a nice addition that ensures a smooth development experience.

Wrap up

Building and publishing a function to Azure is made extremely simple by Visual Studio. Together, these two technologies deliver a frictionless first experience of Cloud Native development. Of course, the journey to production Cloud software is still long and full of challenges, but this quick incursion in the Microsoft ecosystem has demonstrated how accessible and fun the Cloud can be. So, where to go from here? 

Cloud Functions are great to build bots, power backends of web applications, deliver PoCs, orchestrate event-driven workflows, help with monitoring and alerting, building infrastructure… you name it. Whatever you decide to build, make sure you follow the best engineering practices you’d adopt for any other project, such as having an automated, healthy test pyramid, using multiple deployment environments, keeping your infrastructure in code and making automated deployments via CI/CD solutions such as Azure DevOps.

 

 

  • microsoft-azure