Up and running with Azure Functions

Up and running with Azure Functions

January 25, 2021

azureserverlessnodejs

Up and running with Azure Functions

Azure functions or the Azure Function App is the function as a service offering from Microsoft Azure. Even though comparable to Lambda, Azure does things notably different from the pioneer of serverless functions. One of the fundamental differences lies in the fact that, unlike Lambda, individual functions aren’t always completely isolated from each other.

Since the Function App acts as an umbrella for all its underlying functions, they will all share the same runtime, configurations, environment variables, and other resources. There can be up to 100 Function Apps in a Consumption plan. All functions under a Function App will be accessible via the Function App’s endpoint. Eg., myFnApp.azurewebsites.net/myFn01

Azure Functions can be invoked via triggers and bindings which seamlessly integrate to a multitude of Azure services including Storage Queues, Azure Service Bus, Cosmos DB, etc.

  • A list of all the available bindings hand be found here

In this post, we will see how to set up, locally test, deploy and monitor Azure functions part of a Function App.


Setup

One way to create a Function App is via the Azure portal. The pre-requisites, like for any other Azure service, includes a Resource Group and a Storage Account. It is possible to set them up on the fly, as we create the Function App, through the Azure portal. You have to specify the runtime stack, node.js in our case, the version we want to use, and the Azure region to deploy the service in.

Create Function app - basics

We can also specify hosting options like the operating system (Linux / Windows) and the hosting plan. We will go with Linux and the pay-per-use Consumption plan.

Create Function app - hosting

Once created the Function App dashboard allows us to configure and monitor everything including Access Control, Custom Domains, Application Insights, logs, and metric among other things.

Function App dashboard


Working with Azure functions

One of the things I found helpful when working with Azure functions is the Azure Functions extension from the Azure Tools extension pack for VSCode. Install the extension, connect your Azure account and you are good to go.

Azure Tools Extension

It allows us to create Azure functions of any binding type with a couple of clicks and generates the template with the default configurations for us. This can also be achieved via the Azure CLI.

Create new function Function created

The httpTrigger binding type can be used similarly to a Lambda connected to an API Gateway. The function.json holds all the function-specific configurations including allowed HTTP methods.


{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

Let’s create a simple function which takes the name from the request body and sends Hello <name> as the response.


module.exports = async function (context, req) {
	try {
		context.log("req", req);

		let { name } = req.body;

		context.res = {
			body: `Hello ${name}`
		};
		context.done();
	} catch (err) {
		context.log("errors: ", errors);
		context.res = {
			status: 400,
			body: errors
		};
		context.done();
	}
};

To test the function locally, we can either use the native VSCode debugger or the Azure CLI command:

func host start --javascript

Working locally

The value property of local.settings.json can be used to store and access environment variables when developing in the local environment.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "API_KEY": "abcd"
  },
  "Host": {
    "LocalHttpPort": 7071,
    "CORS": "*"
  }
}

Once deployed these env variables will have to be added to applications settings for the Function App. This can be done via the Azure Functions extension as well.

Application settings


Deploying the function

The Azure Functions extension and the CLI enable us to directly deploy the functions to our Azure Function App. But this will overwrite the whole Function App every time with no source control. Instead, we will be using GitHub actions to help us deploy the Function App when changes are pushed.

Let’s start by creating a workflow YAML file that will hold the deployment config under the .github/workflows/ directory. The steps run by the workflow involves setting up the node environment, installing the dependencies specified, building the Function App, and finally deployment. The Publish Profile of the Function App which can be found in the Function App dashboard must be added as a secret to the GitHub account that hosts the repository.

  • Refer this article to know more about using GitHub actions with Azure Function App.
# .github/workflows/fnDeploy.yml

name: Deploy Node.js project to Azure Function App

on:
  [push]

env:
  AZURE_FUNCTIONAPP_NAME: abcdFnApp # set this to your application's name
  AZURE_FUNCTIONAPP_PACKAGE_PATH: "." # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: "12.x" # set this to the node version to use (supports 8.x, 10.x, 12.x)

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout GitHub Action"
        uses: actions/checkout@master

      - name: "Login via Azure CLI"
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Setup Node ${{ env.NODE_VERSION }} Environment
        uses: actions/setup-node@v1
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: "Resolve Project Dependencies Using Npm"
        shell: bash
        run: |
          pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
          npm install
          npm run build --if-present
          npm run test --if-present
          popd

      - name: "Run Azure Functions Action"
        uses: Azure/functions-action@v1
        id: fa
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets.SCM_CREDENTIALS }}

Once deployed the function endpoint can be found in the Azure function dashboard

function dashboard

Logs and monitoring

Invocation logs can be found under the monitor section of the function dashboard. One issue that I always faced when working with Azure functions is the time it takes for the logs to appear in the invocation tab. It usually takes about 5 minutes before the log shows up which can be frustrating when trying to debug in real-time.

Invocation logs

One alternative to this though is the ability to connect to the log streams/application insights. Once connected we will be able to see real-time logs to help debug and monitor. But this, even though works well for the most part, at times can be unreliable. Sometimes the logs will be partial while during others there wouldn’t be any that shows up even after being connected to the stream.

Application Insights

References

For questions and suggestions, feel free to reach out to us on Twitter

Further Reading

Antstack Blog Post
Antstack Blog Post

Are you planning to go to serverless? AntStack is a cloud computing service and consulting company primarily focusing on Serverless Computing. We help companies get up and running with serverless, and we’ll make sure that there are no limits.

Keep track of our socials and connect with us - LinkedIn

event bannerevent bannerevent banner