Deploying Scala code on Azure Functions

 

Interested in running Scala on Azure Functions?? Does Scala run better on Functions than Java? This article will outline how to publish your Scala code to Azure Functions and create a local Azure Functions development environment. + (benchmark below) 

The complete source code for this project is located here.

New 2.0 Runtime

For those of us who work frequently with Azure Functions one thing has been very clear over the few years: Microsoft is investing heavily into Functions, and the changes so far in the 2.0 runtime have made a huge performance impact. Additionally, Microsoft has worked hard to make the deployment to functions easy for “first-class” supported languages like Javascript, Java, C# and as of recently, Python. Unfortunately, there is no built in build and deploy mechanism for Scala yet, but Scala JARs execute on the Function worker with no issue.

Functions Structure

Before digging deep, it’s important to call out the structure of Functions and Function Apps in Azure.

The Function service has two entities: the Function App, and the Function. The Function App is the the collection of individual Functions and is an instance on the Azure Functions Service host. All Functions under the Function App share the same resources within an instance and scale at the time. Function Apps (remember, the collection of Functions) scale independently on the consumption plan of compute allocation.1 This is an important thing to consider when architecting how you deploy your Functions.

A Function App has the following directory structure (our folder names are used here as an example):

wwwroot
— scala-function-app 
—-+ host.json
–ScalaFunction
—-+ function.json
—-+ ScalaFunction.jar

This displays the following view from the Azure portal

Function Configuration Files

These files are necessary to deploy Functions to Azure.

  1. host.json  – This file is the global configuration metadata for all Functions (the Function App). At a minimum, it must specify the runtime version.
  2. function.json  – This is the individual Function configuration metadata. In the Java worker, there are important parameters:
    1.   scriptFile – Location of the JAR, relative to the Function App directory
    2.   entryPoint – Location of method to execute within your application. In this case, this is  Function.run

1. Create the Function Development Environment

  1. Make sure you have JDK 8 installed and your JAVA_HOME set appropriately.
  2. Install .NET Core (needed for the local function host)
  3. Install the Azure Function Core Tools (this will help you run and debug your function locally before deploying)
  4. Install sbt
  5. Clone the Scala example repo from Github

sbt Configuration

sbt needs two important configuration items:

+build.sbt

This adds the Functions Java library to the project and sets our .jar output directory to the local function directory

+plugins.sbt

The Java function worker executes your function via a packaged .JAR. We use the sbt-assembly plugin to create a fat jar with all dependencies included. This JAR will later be uploaded to Azure via the Function Core Tools

2. Converting the Java Function Code to Scala

Most of the time, Java libraries can easily be interacted with in Scala.

The Microsoft documentation here shows an example Java Function class as below:

Converting this code to Scala, we now have the following Scala Class

In this Class, the annotations are very important. Without @FunctionName()  and the @HttpTrigger()  the function will not run. The @FunctionName()  must match the function folder name as shown above. Failure to do so will show the following error when executing the function locally or in Azure:

See the complete conversion in the repo.

3. Build the JAR

The project contains a directory named ‘scala-function-app’. This is our top level Function App directory that will be deployed to Azure. We instruct sbt to deploy our JAR to this directory.

Package the jar with the command  sbt assembly .

4. Test the Function App locally

The Function Core Tools allow you to launch an instance of the Function Host locally on your machine and test your Function. The ‘scala-function-app’ directory

  1. ‘cd’ to the scala-function-app directory within the project
  2. Run the command ‘func host start’

You should see the following output:

Execute a POST with any body message to the shown URL to test your function.

4. Publish the Function App to Azure

  1. Create your Function App – either via Azure CLI or the Portal. Don’t worry about the precreated Functions or configuration files, our deploy will overwrite everything.
  2. Run the command  func azure functionapp publish {function_app_name_in_Azure} This will upload your JAR and configuration files to Azure and deploy your Function App.

That’s it! Your Function App should now be visible via the Azure portal.

Function Benchmarks

Light load testing shows Scala performs slightly (20%) faster than Java when executing a Fibonacci calculation of 20. I understand this may not be the perfect benchmark of a Function, but it definitely rules out Scala being slower than Java on Functions.

100 concurrent user load for 2 minutes was sent to the Java and Scala function at different times:

Java Function benchmark

Scala Function benchmark

Feedback appreciated in the comments below.