Guides: Azure Functions (.NET C#)


Before We Get Started

You will need the following before continuing:

If you are new to Azure Function local development, see the Getting started guide for how to get up and running with your toolchain of choice.

Create a Local Azure Function App

The RavenDB Azure Function template is a template repository on GitHub which means you can either create a new repository derived from the template or clone and push it to a new repository.

This will set up a local Azure Function app that we will deploy to your Azure account at the end of the guide.

Creating a New Repository from the Template

Depending on your environment, there are several ways to clone the template and initialize a new Git repository.
The template repository lists each clone method you can copy & paste directly.

Using npx and the degit tool if you have Node.js installed:

npx degit ravendb/templates/azure-functions/csharp-http my-project
cd my-project
git init

Using Bash or PowerShell:

git clone https://github.com/ravendb/templates my-project
cd my-project
git filter-branch --subdirectory-filter azure-functions/csharp-http
rm -rf .git       # Bash
rm -r -force .git # PowerShell
git init

Install Dependencies

After cloning the repository locally, restore .NET dependencies with dotnet:

dotnet restore

By default, the template is configured to connect to the Live Test instance of RavenDB.
Since this is only for testing purposes, next you will configure the app to connect to your existing RavenDB database.

Starting the Function

You can start the Azure Function locally using:

func start

If you are using Visual Studio Code, you can also debug the function with F5 debugging.

You will see the welcome screen if the template is set up correctly:

.NET template welcome screen

.NET template welcome screen

Configuring Local Connection to RavenDB

To configure the local version of your Azure Functions app to connect to RavenDB, you will need to update the appsettings.json file with the RavenSettings:Urls value and RavenSettings:DatabaseName value.
The default is:

{
  "RavenSettings": {
    "Urls": ["http://live-test.ravendb.net"],
    "DatabaseName": "Northwind"
  }
}

If using an authenticated RavenDB URL, you will need a local client certificate installed.
Learn more about configuring client authentication for RavenDB here.

Certificate Path and Password (Windows and Linux)

To specify the path to a .pfx file, specify a relative or absolute file path using RavenSettings:CertFilePath.

To specify a PFX password, use the .NET User Secrets tool to add a secret locally:

dotnet user-secrets init
dotnet user-secrets set RavenSettings:CertPassword "<CERT_PASSWORD>"

Replace <CERT_PASSWORD> with your PFX password.

Example appsettings.json:

{
  "RavenSettings": {
    "Urls": ["https://a.free.mycompany.ravendb.cloud"],
    "DatabaseName": "company_db",
    "CertFilePath": "a.free.mycompany.ravendb.cloud.with.password.pfx"
  }
}

Certificate Thumbprint (Windows Only)

You can also specify a certificate to use from the CurrentUser\My Windows certificate store by setting RavenSettings:CertThumbprint.

Example appsettings.json:

{
  "RavenSettings": {
    "Urls": ["https://a.free.mycompany.ravendb.cloud"],
    "DatabaseName": "company_db",
    "CertThumbprint": "<CERT_THUMBPRINT>"
  }
}

Creating Function App Resources in Azure

At this point, the local Function app is ready to be deployed. Before you can do that, you need to set up the Function App resources in Azure.

The template includes an ARM deployment option using the Deploy to Azure button. This will open the Azure Portal and walkthrough creating a default Function App with the required resources and app settings.

Follow the guide of your choice in the Microsoft docs. Once the app is created, come back here to finish configuring your database connection.

Upload Your Client Certificate (.pfx)

Once the app is created in the portal, follow these steps to upload the client certificate and make it accessible to your Function.

.NET upload certificate to Azure

.NET upload certificate to Azure

  1. Go to your Azure Functions dashboard in the Portal
  2. Click "Certificates"
  3. Click the "Bring Your Own Certificate" tab
  4. Click "+ Add Certificate" button
  5. Upload the RavenDB client certificate (PFX) file
  6. Enter the certificate password
  7. Once uploaded, click the certificate to view details
  8. Copy the "Thumbprint" for the next step

Do not store certificate password

The Azure portal will only use the certificate password once on upload. You will not need the password in your Functions App, only the public thumbprint.
You can safely delete the password from your device once the certificate is uploaded in the Portal so as not to risk it being discovered.

Configure Application Settings

.NET update Azure app settings

.NET update Azure app settings

  1. Go to your Azure Functions dashboard in the Portal
  2. Click the Application Settings menu
  3. Modify or add app setting for WEBSITE_LOAD_CERTIFICATES to the certificate thumbprint you copied

    .NET WEBSITE_LOAD_CERTIFICATES example

    .NET WEBSITE_LOAD_CERTIFICATES example

  4. Modify or add app setting for RavenSettings__CertThumbprint with the certificate thumbprint you copied

    .NET WEBSITE_LOAD_CERTIFICATES example

    .NET WEBSITE_LOAD_CERTIFICATES example

  5. Modify or add app setting for RavenSettings__Urls with the comma-separated list of RavenDB node URLs to connect to

  6. Modify or add an app setting for RavenSettings__DatabaseName with the database name to connect to

These values will override appsettings.json once deployed on Azure.

Loading multiple certificates

WEBSITE_LOAD_CERTIFICATES makes any specified certificates available in the Windows Certificate Store under the CurrentUser\My location. You can use the wildcard value * for WEBSITE_LOAD_CERTIFICATES to load ALL uploaded certificates for your Function App.
However, it's recommended to be specific and use comma-separated thumbprints so that only allowed certificates are made available. This avoids accidentally exposing a certificate to the application that isn't explicitly used.

Deploying to Azure

Once the Azure app is set up in the portal, you are ready to deploy your app. There are 3 main ways to deploy your new Azure Function app: GitHub actions, command-line, and an extension.

The template has already been set up to use continuous deployment using GitHub Actions.
For the other methods, see Deploying Azure Function apps.

Configure GitHub Secrets

The GitHub actions rely on having a secret environment variable AZURE_FUNCTIONAPP_PUBLISH_PROFILE in your repository secrets.

  1. Go to your Azure Functions dashboard in the Azure Portal
  2. Click "Get Publish Profile"

    download Azure publish profile

    download Azure publish profile

  3. Download the publish profile

  4. Open it and copy the full XML
  5. Go to your GitHub repository's secrets settings

    add GitHub secret for publish profile

    add GitHub secret for publish profile

  6. Add a new secret: AZURE_FUNCTIONAPP_PUBLISH_PROFILE

  7. Paste in the value of the publish profile

Trigger a Deployment

Your repository and GitHub action is now set up. To test the deployment, you can push a commit to the repository.

If you have already committed and pushed, it is likely that the Action failed and you can re-run the job using the new secret variable.

Verify the Connection Works

If the deployment succeeds, the HttpTrigger endpoint should now be available at your Function URL.

Once you open the URL in the browser, you should see a welcome screen like this with the connection information:

.NET Azure Function welcome connected screen

.NET Azure Function welcome connected screen

This means your Azure Functions app is correctly configured and ready to work with RavenDB.

Using RavenDB in the Azure Functions App

The template sets up a singleton DocumentStore and dependency injection for the IAsyncDocumentStore per function invocation which you can inject into Function classes.

Example: Injecting IAsyncDocumentSession

Pass the IAsyncDocumentSession in a function class constructor to make it available to trigger functions:

private readonly IAsyncDocumentSession session;

public HttpTrigger_1(IAsyncDocumentSession session)
{
    this.session = session;
}

[FunctionName("HttpTrigger_1")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
    // Access `session` within the body of the function

    var user = await session.LoadAsync<object>("users/100");

    return new OkObjectResult(user);
}

You can also inject an IDocumentStore to get a reference to the current store instance.

Example: Loading a user

private readonly IAsyncDocumentSession session;

public HttpTrigger_2(IAsyncDocumentSession session)
{
    this.session = session;
}

[FunctionName("HttpTrigger_2")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "{id:int}")] int id,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var user = await session.LoadAsync<object>("users/" + id);

    return new OkObjectResult(user);
}

Learn more about using the RavenDB .NET client SDK here.