How to Develop Azure Functions with YugabyteDB

Develop Azure Functions

Use YugabyteDB as the backend for Azure Functions

In this tutorial, we'll guide you through the steps required to develop and deploy a serverless function using Azure Functions and YugabyteDB.

Serverless functions serve many use cases, including API endpoints, scheduled jobs, and file processing. Azure Functions work with a number of triggers and bindings, which allow developers to define precisely when a function will be invoked and how it will interact with other services.

In the following sections, you will:

  1. Cover the prerequisites for developing an Azure Function backed by our fully managed DBaaS, YugabyteDB Managed.
  2. Deploy a database cluster to Azure on YugabyteDB Managed.
  3. Develop an Azure Function using an HTTP trigger.
  4. Deploy this serverless function to Azure.

Let's begin by installing the dependencies required to begin effectively developing Azure Functions.

What we'll build

First, visit GitHub for the function application we will be deploying to Azure.

We'll develop and deploy an HTTP trigger function, which connects to YugabyteDB and returns the current inventory of our shoe store, YB Shoes.

Prerequisites

Get started on YugabyteDB Managed

For steps on creating a cluster in YugabyteDB Managed, see the Quick start.

For a configuration that provides fault tolerance across availability zones, deploy a three-node cluster on Azure in the westus3 region. However, you can start with an always-free single-node Sandbox cluster.

Deploy a 3-node YugabyteDB Managed cluster to Azure

Add your computer's IP address to the cluster IP allow list so that you can run your serverless functions locally in development.

Now that we have a working cluster in YugabyteDB Managed, let's add some data.

Add data to YugabyteDB

Now that our cluster is running in the cloud, we can seed it with data using the provided schema.sql and data.sql files.

  1. Use the YugabyteDB Cloud Shell to connect to your cluster.
  2. Execute the commands in the schema.sql script against your cluster.
  3. Execute the commands in the data.sql script against your cluster.

With your cluster seeded with data, it's time to build the serverless function to connect to it.

Develop serverless functions

The Azure Functions Core Tools provide a command-line interface for developing functions on your local machine and deploying them to Azure.

  1. Initialize a new Azure Functions project.

    func init YBAzureFunctions --worker-runtime javascript --model V4
    
  2. Create a new HTTP trigger function.

    cd YBAzureFunctions
    func new --template "Http Trigger" --name GetShoeInventory
    
  3. Install the YugabyteDB node-postgres Smart Driver.

    npm install @yugabytedb/pg
    
  4. Update the boilerplate code in GetShoeInventory.js.

    const { app } = require("@azure/functions");
    const { Client } = require("pg");
    
    app.http("GetShoeInventory", {
    methods: ["GET"],
    authLevel: "anonymous",
    handler: async () => {
        // Read the PostgreSQL connection settings from local.settings.json
        console.log("process.env.DB_HOST:", process.env.DB_HOST);
        const client = new Client({
        user: process.env.DB_USERNAME,
        host: process.env.DB_HOST,
        database: "yugabyte",
        password: process.env.DB_PASSWORD,
        port: 5433,
        max: 10,
        idleTimeoutMillis: 0,
        ssl: {
            rejectUnauthorized: true,
            ca: atob(process.env.DB_CERTIFICATE),
            servername: process.env.DB_HOST,
        },
        });
        try {
        // Connect to the PostgreSQL database
        await client.connect();
        // Query YugabyteDB for shoe inventory
        const query =
            "SELECT i.quantity, s.model, s.brand from inventory i INNER JOIN shoes s on i.shoe_id = s.id;";
        const result = await client.query(query);
        // Process the query result
        const data = result.rows;
        // Close the database connection
        await client.end();
        return {
            status: 200,
            body: JSON.stringify(data),
        };
        } catch (error) {
        console.error("Error connecting to the database:", error);
        return {
            status: 500,
            body: "Internal Server Error",
        };
        }
    },
    });
    
  5. Update local.settings.json with the configuration settings required to run the GetShoeInventory function locally.

    # convert the downloaded CA certificate from YugabyteDB Managed to a single line string, then Base64 encode it
    # Azure Configuration Settings forbid special characters, so this ensures the cert can be passed properly to our application
    # Tip: Run this command to convert cert file to base64 encoded single line string:
    # cat /path/to/cert/file | base64
    
    local.settings.json
    ...
    "DB_USERNAME": "admin",
    "DB_PASSWORD": [YUGABYTE_DB_PASSWORD],
    "DB_HOST": [YUGABYTE_DB_HOST],
    "DB_NAME": "yugabyte",
    "DB_CERTIFICATE": [BASE_64_ENCODED_YUGABYTE_DB_CERTIFICATE]
    
  6. Run the function locally.

    func start
    

Test your function in the browser at http://localhost:7071/api/GetShoeInventory.

Now we'll deploy our function to Azure.

Deploy a Function App to Azure

We can deploy our application to Azure using the Azure CLI.

  1. Create a Function App.

    az functionapp create --resource-group RESOURCE_GROUP_NAME --consumption-plan-location eastus2 --runtime node --runtime-version 18 --functions-version 4 --name YBAzureFunctions --storage-account STORAGE_ACCOUNT_NAME
    
  2. Get the outbound addresses for your function app and add them to your YugabyteDB cluster's IP allow list. This ensures that a connection can be made between Azure Functions and YugabyteDB.

    az functionapp show --resource-group RESOURCE_GROUP_NAME --name YBAzureFunctions --query possibleOutboundIpAddresses --output tsv
    

    You can also obtain these addresses in the Networking tab of the Azure portal.

    Locate outbound IP addresses in the Azure portal

  3. Configure the application settings.

    az functionapp config appsettings set -g RESOURCE_GROUP_NAME -n YBAzureFunctions --setting DB_HOST=[YUGABYTE_DB_HOST] DB_USERNAME=admin DB_PASSWORD=[YUGABYTE_DB_PASSWORD] DB_CERTIFICATE=[BASE_64_ENCODED_YUGABYTE_DB_CERTIFICATE]
    
  4. Publish Function App to Azure.

    func azure functionapp publish YBAzureFunctions
    
  5. Verify that the function was published successfully.

    curl https://ybazurefunctions.azurewebsites.net/api/GetShoeInventory
    
    [{"quantity":24,"model":"speedgoat 5","brand":"hoka one one"},{"quantity":74,"model":"adizero adios pro 3","brand":"adidas"},{"quantity":13,"model":"torrent 2","brand":"hoka one one"},{"quantity":99,"model":"vaporfly 3","brand":"nike"}]
    

Wrap-up

As you can see, it's easy to begin developing and publishing database-backed Azure Functions with YugabyteDB.

If you're also interested in building a Node.js web application for YB Shoes using Azure App Service and YugabyteDB, check out the blog Build Applications Using Azure App Service and YugabyteDB.