Skip to content

Choc13/az-function-fsharp-net5

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Example Azure Function using F# on .NET 5

This repo shows a minimal example of how to write an Azure function using F# and run it on .NET 5. It also includes an example of deploying to Azure from your local machine and using GitHub actions.

Gotchas

There were several gotchas that were discovered when trying to get this to work which were often tricky to find in the existing documentation. In fact, all of these gotchas are related to using .NET 5 and apply equally to a C# project.

  1. Isolated .NET Host

    Running the function on .NET 5 requires an isolated .NET host. Specifically, we have to set the environment variable FUNCTIONS_WORKER_RUNTIME to the value "dotnet-isolated". This is because the default host in the functions runtime is still using .NET Core 3.1. We have to set this in both the local.settings.json file for running locally and the ARM template for running in Azure.

  2. Build requires .NET 3 SDK

    Although our code is targeting net5.0 we need both the .NET 5 and .NET Core 3.1 SDK installed in order to build the project. More details can be found in this GitHub issue.

  3. Correct Worker Extensions Packages

    The templates generated by Visual Studio etc don't seem to include the correct NuGet function extensions packages for the isolated hosting model. See the Function.fsproj file for the correct packages to use with the isolated hosting model. Note, this project is using Microsoft.Azure.Functions.Worker.Extensions.Timer because this basic example just uses a simple timer trigger, you might need a different extension package if you're using a different trigger, e.g. Blob triggers require Microsoft.Azure.Functions.Worker.Extensions.Storage.

  4. _FunctionsSkipCleanOutput Attribute

    Again, the templates don't always require all of the necessary MSBuild settings. The .fsproj should contain <_FunctionsSkipCleanOutput>True</_FunctionsSkipCleanOutput>.

  5. <None Include=> instead of <None Update=>

    Another issue with the stock templates is that the settings files (host.json and local.settings.json) have the wrong compile directives, they should use <None Include=>.

  6. Use dotnet build instead of dotnet publish

    When publishing an ASP.NET app it's typical to run dotnet publish to generate the necessary runtime artifacts such as a web.config. Oddly, with an Azure function we just run dotnet build instead. See the GitHub workflow for an example.

  7. Bootstrap the Host

    This one isn't so much of a gotcha, but it's probably worth pointing out that in order to use the dotnet-isolated runtime we have to bootstrap the host ourselves. See Program.fs for a minimal example that works for this simple function. Other functions that use other azure services will need to add the necessary bootstrapping code to configure those services. See the docs on isolated hosts for more information.

Deployment

Prerequisites

Before getting started you'll need an Azure subscription and a resource group, you'll also need to have the az cli installed.

You can create the resource group with the az cli like this:

az group create -n <resource-group-name> -l <location>

Steps

  1. Build the function app.

    dotnet build src/Function -c Release -o .publish/func
  2. Deploy to Azure

    ./deploy.sh .publish/func/ -g <name-of-your-resource-group>

GitHub

This repo also includes a GitHub workflow that will run the above steps on each commit to the master branch.

Running Locally

Prerequisites

You will need the following tools installed on your machine, see this document for full instructions:

Steps

  1. Ensure the local storage connection string is set. In local.settings.json the following config value should be set under the Values section.

    "AzureWebJobsStorage": "UseDevelopmentStorage=true"

    This tells the function to look for a storage account on the default development port and with the default development account key.

  2. Start Azurite (alter the paths if you want to use different locations to store data and logs)

    azurite --location ~/.azurite --debug ~/.azurite/debug.log
  3. Start the function

    # Must be run from the src/Function directory
    func start

Issues deploying this sample, other questions relating to Azure functions with F#?

Open an issue and let me know.

About

A minimal example of creating an Azure function using F# on .NET 5. with bonus GitHub actions deployment

Topics

Resources

Stars

Watchers

Forks