Create your first function on Azure Arc using a custom container (preview)
In this quickstart, you create an Azure Functions project running in a custom container and deploy it to an Azure Arc-enabled Kubernetes cluster from your Docker Hub account. To learn more, see App Service, Functions, and Logic Apps on Azure Arc. This scenario only supports function apps running on Linux.
Note
Support for running functions on an Azure Arc-enabled Kubernetes cluster is currently in preview.
Prerequisites
On your local computer:
- .NET 6.0 SDK
- Azure Functions Core Tools version 4.x
- Azure CLI version 2.4 or later
- Docker
- Docker ID
Create an App Service Kubernetes environment
Before you begin, you must create an App Service Kubernetes environment for an Azure Arc-enabled Kubernetes cluster.
Note
When you create the environment, make sure to make note of both the custom location name and the name of the resource group that contains the custom location. You can use these to find the custom location ID, which you'll need when creating your function app in the environment.
If you didn't create the environment, check with your cluster administrator.
Add Azure CLI extensions
Launch the Bash environment in Azure Cloud Shell.
Because these CLI commands are not yet part of the core CLI set, add them with the following commands:
az extension add --upgrade --yes --name customlocation
az extension remove --name appservice-kube
az extension add --upgrade --yes --name appservice-kube
Create the local function project
In Azure Functions, a function project is the context for one or more individual functions that each responds to a specific trigger. All functions in a project share the same local and hosting configurations. In this section, you create a function project that contains a single function.
Run the
func init
command, as follows, to create a functions project in a folder named LocalFunctionProj with the specified runtime:func init LocalFunctionProj --dotnet --docker
The
--docker
option generates aDockerfile
for the project, which defines a suitable custom container for use with Azure Functions and the selected runtime.Navigate into the project folder:
cd LocalFunctionProj
This folder contains the
Dockerfile
and other files for the project, including configurations files named local.settings.json and host.json. By default, the local.settings.json file is excluded from source control in the .gitignore file. This exclusion is because the file can contain secrets that are downloaded from Azure.Open the generated
Dockerfile
and locate the3.0
tag for the base image. If there's a3.0
tag, replace it with a3.0.15885
tag. For example, in a JavaScript application, the Docker file should be modified to haveFROM mcr.microsoft.com/azure-functions/node:3.0.15885
. This version of the base image supports deployment to an Azure Arc-enabled Kubernetes cluster.Add a function to your project by using the following command, where the
--name
argument is the unique name of your function (HttpExample) and the--template
argument specifies the function's trigger (HTTP).func new --name HttpExample --template "HTTP trigger" --authlevel "anonymous"
Build the container image and test locally
The Dockerfile in the project root describes the minimum required environment to run the function app in a container. The complete list of supported base images for Azure Functions can be found in the Azure Functions base image page.
In the root project folder, run the docker build command, and provide a name,
azurefunctionsimage
, and tag,v1.0.0
.The following command builds the Docker image for the container.
docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .
In this example, replace
<DOCKER_ID>
with your Docker Hub account ID. When the command completes, you can run the new container locally.To test the build, run the image in a local container using the docker run command, with the adding the ports argument,
-p 8080:80
.docker run -p 8080:80 -it <docker_id>/azurefunctionsimage:v1.0.0
Again, replace
<DOCKER_ID
with your Docker ID and adding the ports argument,-p 8080:80
After the image is running in a local container, browse to
http://localhost:8080/api/HttpExample?name=Functions
, which should display the same "hello" message as before. Because the HTTP triggered function uses anonymous authorization, you can still call the function even though it's running in the container. Function access key settings are enforced when running locally in a container. If you have problems calling the function, make sure that access to the function is set to anonymous.
After you've verified the function app in the container, stop docker with Ctrl+C.
Push the image to Docker Hub
Docker Hub is a container registry that hosts images and provides image and container services. To share your image, which includes deploying to Azure, you must push it to a registry.
If you haven't already signed in to Docker, do so with the docker login command, replacing
<docker_id>
with your Docker ID. This command prompts you for your username and password. A "Login Succeeded" message confirms that you're signed in.docker login
After you've signed in, push the image to Docker Hub by using the docker push command, again replacing
<docker_id>
with your Docker ID.docker push <docker_id>/azurefunctionsimage:v1.0.0
Depending on your network speed, pushing the image the first time might take a few minutes (pushing subsequent changes is much faster). While you're waiting, you can proceed to the next section and create Azure resources in another terminal.
Get the custom location
To be able to create a function app in a custom location, you'll need to get information about the environment.
Get the following information about the custom location from your cluster administrator (see Create a custom location).
customLocationGroup="<resource-group-containing-custom-location>"
customLocationName="<name-of-custom-location>"
Get the custom location ID for the next step.
customLocationId=$(az customlocation show \
--resource-group $customLocationGroup \
--name $customLocationName \
--query id \
--output tsv)
Create Azure resources
Before you can deploy your container to your new App Service Kubernetes environment, you need to create two more resources:
- A Storage account. While this article creates a storage account, in some cases a storage account may not be required. For more information, see Azure Arc-enabled clusters in the storage considerations article.
- A function app, which provides the context for running your container. The function app runs in the App Service Kubernetes environment and maps to your local function project. A function app lets you group functions as a logical unit for easier management, deployment, and sharing of resources.
Note
Function apps run in an App Service Kubernetes environment on a Dedicated (App Service) plan. When you create your function app without an existing plan, a plan is created for you.
Create Storage account
Use the az storage account create command to create a general-purpose storage account in your resource group and region:
az storage account create --name <STORAGE_NAME> --location westeurope --resource-group myResourceGroup --sku Standard_LRS
Note
In some cases, a storage account may not be required. For more information, see Azure Arc-enabled clusters in the storage considerations article.
In the previous example, replace <STORAGE_NAME>
with a name that is appropriate to you and unique in Azure Storage. Names must contain three to 24 characters numbers and lowercase letters only. Standard_LRS
specifies a general-purpose account, which is supported by Functions. The --location
value is a standard Azure region.
Create the function app
Run the az functionapp create command to create a new function app in the environment.
az functionapp create --resource-group MyResourceGroup --name <APP_NAME> --custom-location <CUSTOM_LOCATION_ID> --storage-account <STORAGE_NAME> --functions-version 4 --runtime dotnet --deployment-container-image-name <DOCKER_ID>/azurefunctionsimage:v1.0.0
In this example, replace <CUSTOM_LOCATION_ID>
with the ID of the custom location you determined for the App Service Kubernetes environment. Also, replace <STORAGE_NAME>
with the name of the account you used in the previous step, <APP_NAME>
with a globally unique name appropriate to you, and <DOCKER_ID>
with your Docker Hub ID.
The deployment-container-image-name parameter specifies the image to use for the function app. You can use the az functionapp config container show command to view information about the image used for deployment. You can also use the az functionapp config container set command to deploy from a different image.
When you first create the function app, it pulls the initial image from your Docker Hub. You can also Enable continuous deployment to Azure from Docker Hub.
To learn how to enable SSH in the image, see Enable SSH connections.
Set required app settings
Run the following commands to create an app setting for the storage account connection string:
storageConnectionString=$(az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <STORAGE_NAME> --query connectionString --output tsv)
az functionapp config appsettings set --name <app_name> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=$storageConnectionString
This code must be run either in Cloud Shell or in Bash on your local computer. Replace <STORAGE_NAME>
with the name of the storage account and <APP_NAME>
with the function app name.
Invoke the function on Azure
Because your function uses an HTTP trigger, you invoke it by making an HTTP request to its URL in the browser or with a tool like curl.
Copy the complete Invoke URL shown in the output of the publish command into a browser address bar, appending the query parameter ?name=Functions
. The browser should display similar output as when you ran the function locally.
Next steps
Now that you have your function app running in a container an Azure Arc-enabled App Service Kubernetes environment, you can connect it to Azure Storage by adding a Queue Storage output binding.
Feedback
Submit and view feedback for