DEV Community

Cover image for Kotlin and Azure Functions - Automating the deployment
Darren Fuller
Darren Fuller

Posted on

Kotlin and Azure Functions - Automating the deployment

Recently I needed to write an Azure Function app that uses the Apache POI library for getting the text from Microsoft Word 94 documents (and yes, I am fully aware that the year is currently 2024, but some people still have 30 year old documents kicking around!).

Being somewhat allergic to coding in Java (this is a personal thing, if you like Java then good for you) I decided to try out writing the code using Kotlin from JetBrains instead. I'm already using IntelliJ as I work with Apache Spark using Scala, so the tooling was already there and ready to go for this.

Microsoft, unexpectedly, have an article about creating Azure Function apps using Kotlin, so this was a great start and, pretty quickly, I had a version of my function app ready to try out.

 Debugging

This isn't as straight forward as just running a debug configuration unfortunately, it would be nice if it was, but it's honestly not too bad either. The Microsoft article talks about how to do it, and once you get into the habit of running the app and then running a configuration to attach the debugger, it just starts to flow.

So, running locally I have an Azure Function app, written in Kotlin, using the Apache POI library, extracting text from a Wore 94 document (it kills me a little bit every time I write that part). So I opened up HTTPie and started firing sample documents at it

IntelliJ running and debugging the code

API being called from HTTPie

It works great, so next I want to deploy this thing, and that's where the smooth ride hits a few bumps.

 Deployment

In the article it tells you to just run the azure-functions:deploy Maven target. It somewhat skips over the fact that you should probably first open up the pom.xml file and do things like change the resource group name, function app name, and the app region. These might seem trivial, but if you have issues with data leaving certain regions then they become really important.

So, first up, change the pom.xml file, specifically these values in the properties section.

  • functionAppName
  • functionAppRegion
  • functionResourceGroup

Having done that I tried to run the maven target again and... failed.

But it failed because it was complaining that it couldn't read the azureProfile.json or accessTokens.json files and that I should check that I'm logged in using the Azure CLI.

This is weird because I had just created the resource group and a few other things for my deployment using the CLI. But I logged in again and tried again and still the same error!

A bit of searching around the web and it turns out that the Azure CLI had been updated a while ago and changed how it was handling tokens, but the Maven Archtype hasn't been updated to reflect this! So, what next?

Well, most deployments to Azure Functions work by packaging up the function app, producing a zip, and then pushing this up. There are other ways, but this works well and is pretty robust. But it's all hidden away in the target, so how can we replicate what it does. We can do this fairly easily it turns out.

There are a few steps we want to follow.

  1. Clean everything up
  2. Package the app
  3. Create the zip
  4. Deploy the zip

Cleaning things up is easy, we can just run mvn clean and we're done.

Packaging we need to run a couple of things. First is the mvn package target to build our application, and then the next is the mvn azure-functions:package target which creates our directory structure that we need to be able to publish the app (this is the really important step).

Once both of these have been executed, if we look under the target directory we can see a new azure-functions directory which contains everything we need, all the jar files, the host.json file and more.

Contents of the target directory after packaging

Now, we're just creating a zip to deploy, so in the command line we move to the target/azure-functions/<function app name> folder and run the following.

> zip -r ../../../deploy.zip *
Enter fullscreen mode Exit fullscreen mode

That will create a deploy.zip file in the root of the source directory with all the contents of the packaged function app directory within it.

Then, we publish the zip to our function app (you need to create that first by the way, as a Java 8 function app) with the following command.

> az functionapp deployment source config-zip -g <resource group name> -n <function app name> --src ./deploy.zip
Enter fullscreen mode Exit fullscreen mode

And that's it, the function app is deployed. You can then grab the URL from the Azure Portal and change the URL in HTTPie, send the document, and get the response.

HTTPie showing response from deployed application

What I ended up doing was putting all of the steps into a Makefile so I could just run make deploy whenever I wanted to push a new version

clean:
    mvn clean

package: clean
    mvn package
    mvn azure-functions:package

deploy: package
    cd ./target/azure-functions/<app name>; zip -r ../../../deploy.zip *
    az functionapp deployment source config-zip -g <resource group name> -n <func app name> --src ./deploy.zip
    rm deploy.zip
Enter fullscreen mode Exit fullscreen mode

Putting in the dependencies meant that I only needed to execute the deploy step, instead of remembering to clean and package as well.

Wrapping up

Pretty quickly I ended up with a function app deployed, written in Kotlin, which could read and extract text from Word 94 (sob sob sob) file. Other than working out the deployment process it went really smoothly and it runs incredibly well.

I'm probably not quite ready to give up C# and dotnet to use this for everything, but this is a nice option when a Java based solution is the better option.

Top comments (0)