Running Azure Functions everywhere

Today, I have demoed at European Collaboration Summit how to run Azure Functions in:

  • Azure (as default deployment, not described here)
  • Locally (On-Prem)
  • Locally in Docker container
  • In Azure in Docker Container inside of AppService
  • In Azure in Docker Container inside of Azure Container Instance Service

First of all, I have discussed about hexagonal architecture, which is very common when it comes to integration. Especially in this context, Azure Functions offers an interesting programming model, rather than building a complete applications on this stack.Following picture shows hexagonal architecture.

When thinking about Azure Functions binding concept, you will recognize that behind the scene Azure Functions is build with this architecture in mind.

To create function in docker container execute following:

func init . --docker 

This will NOT create a function, but a dockerfile. Currentlly this file looks like:

FROM microsoft/dotnet:2.2-sdk AS installer-env

COPY . /src/dotnet-function-app
RUN cd /src/dotnet-function-app && \
    mkdir -p /home/site/wwwroot && \
    dotnet publish *.csproj --output /home/site/wwwroot

FROM mcr.microsoft.com/azure-functions/dotnet:2.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]

AFter all, create your function with command line, VS code or VS Studio.

func new

Run locally

After this, you can run the function locally with:

fnc start

Run in docker contaner locally

As next function application needs to be deployed in docker container.

We need to build a new image with our function:

docker build -t collabfunc:v1 . 

Assuming that function is triggered with HttpListener, you can run it as follows:

docker run –it –-rm –p 8080:80 collabfunc:v1

Assuming that function is triggered with ServiceBus message sent to queue:

docker run -it --rm --env SbConnStr="Endpoint=sb://bastasample.servicebus.windows.net/;***" collabfunc:v1

This all was fine, but it is still running locally. Now, let's publish it to Azure. I have to tag the new image and finally to push it to my private Azure repository with name: damir.azurecr.io:

docker tag collabfunc :v1 damir.azurecr.io/ collabfunc:v1 
docker push damir.azurecr.io/ collabfunc:v1 

Run in AppService

As next I will create the function artifact in Azure with following script:

az group create --name RG-COLLAB --location westeurope

az storage account create --name eucollabstorage --location westeurope --resource-group RG-COLLAB --sku Standard_LRS

az appservice plan create --name CollabAppServicePlan --resource-group RG-COLLAB --sku B1 --is-linux
az functionapp create --name azcollabfunc --storage-account eucollabstorage --resource-group RG-COLLAB --plan CollabAppServicePlan --deployment-container-image-name damir.azurecr.io/mydockerimage:v1.0.0

And, finally I said good bye:

az group delete --name RG-COLLAB

Run in Azure Container Instances

Sometimes, you do not want to run it in AppService. This is perfectly fine. You can run it in any cloud, which can run containers.

Here is how I have created the instance:

az container create --resource-group RG-COLLAB --name mycollabfunc --image damir.azurecr.io/collab:v1 --ip-address public --ports 80 --os-type linux --registry-login-server damir.azurecr.io --registry-username damir --registry-password "***" -e SbConnStr="***"