Build Azure Functions on WSL and deploy them to Docker using VS Code on Windows

By Mirek on (tags: azure, Azure Functions, linux, Visual Studio Code, WSL, categories: architecture, tools, code)

The title of this post might be a little unclear, but that’s what it is about. Keep reading to get it clarified…

The scenario is following:

  1. I’m running Windows 11 development machine
  2. I have Visual Studio Code installed and I want to use it to develop my Azure Function
  3. I have Windows Subsystem Linux (WSL) enabled and configured on my machine
  4. I have Docker installed locally as well
  5. I want to develop and build Azure Functions on linux WSL distro, but using my VS Code from Windows
  6. Then I want to deploy the AF to a linux based docker container right from the WSL environment

Someone would ask: Is it possible at all?

Thanks to some nice built in WSL integrations from Docker, VS Code and Windows itself, it is absolutelly possible and quite straightforward, I have to say.

Ok, but why do I need to build an azure function from WSL? Can’t I just build it on Windows and deploy to Docker container ?
Well in most cases this would be sufficient, unless you are using some linux specific requirements. As an example, recently I’ve been developing a Vega js rendering function. I wanted this function to be hosted as Linux based Azure Fucntion. Unfortunatelly some of the node packages used by Vega were using nativelly build libraries and when installed from Windows machine they were build against Windows architecture. That caused a problem when the project were deployed to linux distro (that internally build libraries could not be simply loaded). So the solution was to basically rebuild node packages on linux, before the zip deployment were prepared.

So without any further ado, lets see how to configure the environment.

Prerequisites

Assuming you have WSL enabled, Visual Studio Code and Docker installed follow these steps:

  1. Enable your Docker WSL backend. Follow this guide for details.
    AFwslVSCode_003
  2. Install WSL VS Code extension according to this guide
  3. Now in VS Code command pallete select option “WSL: New WSL Window”
    AFwslVSCode_001
  4. New VS Code window will open which is now working on you WSL linux distro
  5. Open the VS Code terminal (CTRL+~) for running linux commands
  6. Install Azure CLI
    Follow this guide, but all you need to do is to call in the wsl terminal following command:
    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

  7. Install Azure Core Tools by following this instructions
  8. Now you should be ready to develop and deploy you Azure function. In case you still encounter some problems check this guide.

Develop your Azure Function in WSL

Now lets create the function. We will generally follow this Microsoft guide.

  1. Open your WSL terminal, navigate to your /home/<user> directory, create new folder in it called myazurefunction.
  2. Now start Visual Studio Code for WSL and open the folder created above
  3. Then in the terminal let’s initialize the Azure Function project structure    
    func init --worker-runtime node --language javascript --docker
  4. And create the actual function
    func new --name MyAzureFunction --template "HTTP trigger" --authlevel anonymous

    We will get the node.js sample Azure Function code in the project.
    AFwslVSCode_004

Build and deploy to Docker

To build and run a docker image with our Azure function run following instructions in the WSL terminal. All available Azure Function images can be found here.

docker build --tag myazurefucntion:v1.0.0 .
docker run -p 8080:80 -it myazurefunction:v1.0.0

You should be able to see running container in your Docker

AFwslVSCode_005

Lets now test the function from our windows machine. Navigate your browser to

localhost:8080

and you should see the default Azure Function starting page

AFwslVSCode_006

Now go to command line and execute

C:\>curl http://localhost:8080/api/myazurefunction?name=Mirek

which should return a message from the sample azure function

Hello, Mirek. This HTTP triggered function executed successfully.

That’s it!