DEV Community

Cover image for Deploy Azure Functions using Azure Container Registry
Jack Lin
Jack Lin

Posted on

Deploy Azure Functions using Azure Container Registry

Develop in Linux through the command line with:

  • .NET 6.0 SDK
  • Azure Functions Core Tools 4.x
  • Azurite storage emulator
  • Azure CLI 2.4.0 or newer
  • Docker

Create Project

Use the following command to create a Timer Trigger function in the current directory, and generate the default Dockerfile.

func init --name ContainerApp --worker-runtime dotnet --docker func new --name TimerTriggerExample --template "timer trigger" 
Enter fullscreen mode Exit fullscreen mode

First, run Azurite and then test the function app:

azurite -l azurite_workspace func start 
Enter fullscreen mode Exit fullscreen mode

After testing the app, package the image and run it. Note that when running with docker, you need to set AzureWebJobsStorage to UseDevelopmentStorage=true and simulate storage through Azurite. Enter the name of your Azure Container Registry in the ACR_NAME environment variable in the following command block:

export ACR_NAME=<your azure container registry name> docker build -t ${ACR_NAME}.azurecr.io/container-app:latest . docker run --name container-app -p 8000:80 --network host \ -e AzureWebJobsStorage="UseDevelopmentStorage=true" ${ACR_NAME}.azurecr.io/container-app:latest 
Enter fullscreen mode Exit fullscreen mode

Please note that Azure Functions containers cannot currently run directly on Mac M1.

By the way, Azurite also provides a Docker image that can be run directly with the following command:

docker run --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 -d mcr.microsoft.com/azure-storage/azurite 
Enter fullscreen mode Exit fullscreen mode

After testing the local image, push it to Azure Container Registry:

az login az acr login -n ${ACR_NAME} docker push ${ACR_NAME}.azurecr.io/container-app:latest 
Enter fullscreen mode Exit fullscreen mode

You can then deploy Azure Functions using Azure Container Registry in two ways:

Method 1: Admin Credentials

Give Functon App a Container Registry account password, so that Function App can log in to Container Registry and pull the image file through this set of account password.

First, create a resource group in Azure Portal, fill in the name of this resource group into the RG_NAME environment variable in the command block below, and create and deploy the resources required by Azure Function in this resource group:

export ACR_NAME=<azure container registry name> export RG_NAME=<function app resource group> export APP_NAME=<function app name> export STORAGE_NAME=<storage account name> # Create a storage account az storage account create --name ${STORAGE_NAME} --resource-group ${RG_NAME} --sku Standard_LRS --kind StorageV2 # Create App Service Plan az appservice plan create --name PlanB1 --resource-group ${RG_NAME} --is-linux --sku B1 # Get the username of ACR az acr credential show -n ${ACR_NAME} --query username --output tsv # Get ACR password az acr credential show -n ${ACR_NAME} --query passwords[0].value --output tsv # Create/re-deploy the Function App, set all the necessary information at once az functionapp create --name ${APP_NAME} --storage-account ${STORAGE_NAME} --resource-group ${RG_NAME} \ --plan PlanB1 --functions-version 4 \ --deployment-container-image-name ${ACR_NAME}.azurecr.io/container-app:latest \ --docker-registry-server-password <acr password> \ --docker-registry-server-user <acr username> 
Enter fullscreen mode Exit fullscreen mode

That's it.

Method 2: Managed Identity

Setup an Identity for the Function App, and let Container Registry give it the "AcrPull" permission.

export ACR_NAME=<azure container registry name> export RG_NAME=<function app resource group> export APP_NAME=<function app name> export STORAGE_NAME=<storage account name> # Create a storage account az storage account create --name ${STORAGE_NAME} --resource-group ${RG_NAME} --sku Standard_LRS --kind StorageV2 # Create App Service Plan az appservice plan create --name PlanB1 --resource-group ${RG_NAME} --is-linux --sku B1 # Create a Function App and specify the address of the image az functionapp create --name ${APP_NAME} --storage-account ${STORAGE_NAME} --resource-group ${RG_NAME} \ --plan PlanB1 --functions-version 4 \ --deployment-container-image-name ${ACR_NAME}.azurecr.io/container-app:latest # Set an Identity for the Function App and get the principalId az functionapp identity assign --resource-group ${RG_NAME} --name ${APP_NAME} --query principalId --output tsv # get subscriptionId az account show --query id --output tsv # Give Function App "AcrPull" permission az role assignment create --assignee <principal-id> \ --scope /subscriptions/<subscription-id>/resourceGroups/<container registry resource group>/providers/Microsoft.ContainerRegistry/registries/${ACR_NAME} \ --role "AcrPull" # Set the permission to pull from Container Registry that must be authenticated by Identity az resource update --ids /subscriptions/<subscription-id>/resourceGroups/${RG_NAME}/providers/Microsoft.Web/sites/${APP_NAME}/config/web --set properties.acrUseManagedIdentityCreds=True # Deploy Function App az functionapp config container set --name ${APP_NAME} --resource-group ${RG_NAME} \ --docker-custom-image-name ${ACR_NAME}.azurecr.io/container-app:latest \ --docker-registry-server-url https://${ACR_NAME}.azurecr.io 
Enter fullscreen mode Exit fullscreen mode

At this time, the terminal will display "No credential was provided to access Azure Container Registry. Trying to look up...", azure will automatically apply the current identity to log in to ACR.

Top comments (2)

Collapse
 
tjoudeh profile image
Taiseer Joudeh

Thanks for sharing this, was easy to follow up. The params --docker-custom-image-name and --docker-registry-server-url are deprecated now. Cli will suggest the new names.

Collapse
 
blueskyson profile image
Jack Lin

Thanks for the feedback. Will try again and update the command later.