title | description | ms.assetid | ms.topic | ms.date | ms.custom |
---|---|---|---|---|---|
Automate function app resource deployment to Azure |
Learn how to build an Azure Resource Manager template that deploys your function app. |
d20743e3-aab6-442c-a836-9bcea09bfd32 |
conceptual |
04/03/2019 |
fasttrack-edit, devx-track-azurepowershell |
You can use an Azure Resource Manager template to deploy a function app. This article outlines the required resources and parameters for doing so. You might need to deploy other resources, depending on the triggers and bindings in your function app.
For more information about creating templates, see Authoring Azure Resource Manager templates.
For sample templates, see:
- ARM templates for function app deployment
- Function app on Consumption plan
- Function app on Azure App Service plan
An Azure Functions deployment typically consists of these resources:
Resource | Requirement | Syntax and properties reference |
---|---|---|
A function app | Required | Microsoft.Web/sites |
An Azure Storage account | Required | Microsoft.Storage/storageAccounts |
An Application Insights component | Optional | Microsoft.Insights/components |
A hosting plan | Optional1 | Microsoft.Web/serverfarms |
1A hosting plan is only required when you choose to run your function app on a Premium plan or on an App Service plan.
Tip
While not required, it is strongly recommended that you configure Application Insights for your app.
An Azure storage account is required for a function app. You need a general purpose account that supports blobs, tables, queues, and files. For more information, see Azure Functions storage account requirements.
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2019-06-01",
"location": "[resourceGroup().location]",
"kind": "StorageV2",
"sku": {
"name": "[parameters('storageAccountType')]"
}
}
You must also specify the AzureWebJobsStorage
property as an app setting in the site configuration. If the function app doesn't use Application Insights for monitoring, it should also specify AzureWebJobsDashboard
as an app setting.
The Azure Functions runtime uses the AzureWebJobsStorage
connection string to create internal queues. When Application Insights is not enabled, the runtime uses the AzureWebJobsDashboard
connection string to log to Azure Table storage and power the Monitor tab in the portal.
These properties are specified in the appSettings
collection in the siteConfig
object:
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]"
},
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]"
}
]
Application Insights is recommended for monitoring your function apps. The Application Insights resource is defined with the type Microsoft.Insights/components and the kind web:
{
"apiVersion": "2015-05-01",
"name": "[variables('appInsightsName')]",
"type": "Microsoft.Insights/components",
"kind": "web",
"location": "[resourceGroup().location]",
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('functionAppName'))]": "Resource"
},
"properties": {
"Application_Type": "web",
"ApplicationId": "[variables('appInsightsName')]"
}
},
In addition, the instrumentation key needs to be provided to the function app using the APPINSIGHTS_INSTRUMENTATIONKEY
application setting. This property is specified in the appSettings
collection in the siteConfig
object:
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2015-05-01').InstrumentationKey]"
}
]
The definition of the hosting plan varies, and can be one of the following:
- Consumption plan (default)
- Premium plan
- App Service plan
The function app resource is defined by using a resource of type Microsoft.Web/sites and kind functionapp:
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"location": "[resourceGroup().location]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
]
}
Important
If you are explicitly defining a hosting plan, an additional item would be needed in the dependsOn array: "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
A function app must include these application settings:
Setting name | Description | Example values |
---|---|---|
AzureWebJobsStorage | A connection string to a storage account that the Functions runtime uses for internal queueing | See Storage account |
FUNCTIONS_EXTENSION_VERSION | The version of the Azure Functions runtime | ~4 |
FUNCTIONS_WORKER_RUNTIME | The language stack to be used for functions in this app | dotnet , node , java , python , or powershell |
WEBSITE_NODE_DEFAULT_VERSION | Only needed if using the node language stack on Windows, specifies the version to use |
~14 |
These properties are specified in the appSettings
collection in the siteConfig
property:
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
}
]
}
}
The Consumption plan automatically allocates compute power when your code is running, scales out as necessary to handle load, and then scales in when code is not running. You don't have to pay for idle VMs, and you don't have to reserve capacity in advance. To learn more, see Azure Functions scale and hosting.
For a sample Azure Resource Manager template, see Function app on Consumption plan.
A Consumption plan doesn't need to be defined. When not defined, a plan is automatically be created or selected on a per-region basis when you create the function app resource itself.
The Consumption plan is a special type of serverfarm
resource. You can specify it by using the Dynamic
value for the computeMode
and sku
properties, as follows:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Y1",
"tier": "Dynamic",
"size": "Y1",
"family": "Y",
"capacity":0
},
"properties": {
"name":"[variables('hostingPlanName')]",
"computeMode": "Dynamic"
}
}
To run your app on Linux, you must also set the property "reserved": true
for the serverfarms
resource:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Y1",
"tier": "Dynamic",
"size": "Y1",
"family": "Y",
"capacity":0
},
"properties": {
"name":"[variables('hostingPlanName')]",
"computeMode": "Dynamic",
"reserved": true
}
}
When you explicitly define your Consumption plan, you must set the serverFarmId
property on the app so that it points to the resource ID of the plan. Make sure that the function app has a dependsOn
setting that also references the plan.
The settings required by a function app running in Consumption plan differ between Windows and Linux.
On Windows, a Consumption plan requires another two other settings in the site configuration: WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
and WEBSITE_CONTENTSHARE
. This property configures the storage account where the function app code and configuration are stored.
For a sample Azure Resource Manager template, see Azure Function App Hosted on Windows Consumption Plan.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
}
]
}
}
}
Important
Do not need to set the WEBSITE_CONTENTSHARE
setting in a deployment slot. This setting is generated for you when the app is created in the deployment slot.
The function app must have set "kind": "functionapp,linux"
, and it must have set property "reserved": true
. Linux apps should also include a linuxFxVersion
property under siteConfig. If you are just deploying code, the value for this is determined by your desired runtime stack in the format of runtime|runtimeVersion. For example: python|3.7
, node|14
and dotnet|3.1
.
The WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
and WEBSITE_CONTENTSHARE
settings aren't supported on Linux Consumption plan.
For a sample Azure Resource Manager template, see Azure Function App Hosted on Linux Consumption Plan.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp,linux",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"linuxFxVersion": "node|14",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', parameters('functionAppName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
}
]
}
}
}
The Premium plan offers the same scaling as the Consumption plan but includes dedicated resources and extra capabilities. To learn more, see Azure Functions Premium Plan.
A Premium plan is a special type of "serverfarm" resource. You can specify it by using either EP1
, EP2
, or EP3
for the Name
property value in the sku
as following:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "ElasticPremium",
"name": "EP1",
"family": "EP"
},
"properties": {
"name": "[parameters('hostingPlanName')]",
"maximumElasticWorkerCount": 20
},
"kind": "elastic"
}
To run your app on Linux, you must also set property "reserved": true
for the serverfarms resource:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "ElasticPremium",
"name": "EP1",
"family": "EP"
},
"properties": {
"name": "[parameters('hostingPlanName')]",
"maximumElasticWorkerCount": 20,
"reserved": true
},
"kind": "elastic"
}
For function app on a Premium plan, you will need to set the serverFarmId
property on the app so that it points to the resource ID of the plan. You should ensure that the function app has a dependsOn
setting for the plan as well.
A Premium plan requires another settings in the site configuration: WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
and WEBSITE_CONTENTSHARE
. This property configures the storage account where the function app code and configuration are stored, which are used for dynamic scale.
For a sample Azure Resource Manager template, see Azure Function App Hosted on Premium Plan.
The settings required by a function app running in Premium plan differ between Windows and Linux.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
}
]
}
}
}
Important
You don't need to set the WEBSITE_CONTENTSHARE
setting because it's generated for you when the site is first created.
The function app must have set "kind": "functionapp,linux"
, and it must have set property "reserved": true
. Linux apps should also include a linuxFxVersion
property under siteConfig. If you are just deploying code, the value for this is determined by your desired runtime stack in the format of runtime|runtimeVersion. For example: python|3.7
, node|14
and dotnet|3.1
.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp,linux",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"linuxFxVersion": "node|14",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
}
]
}
}
}
In the App Service plan, your function app runs on dedicated VMs on Basic, Standard, and Premium SKUs, similar to web apps. For details about how the App Service plan works, see the Azure App Service plans in-depth overview.
For a sample Azure Resource Manager template, see Function app on Azure App Service plan.
An App Service plan is defined by a "serverfarm" resource. You can specify the SKU as follows:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "Standard",
"name": "S1",
"size": "S1",
"family": "S",
"capacity": 1
}
}
To run your app on Linux, you must also set property "reserved": true
for the serverfarms resource:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "Standard",
"name": "S1",
"size": "S1",
"family": "S",
"capacity": 1
},
"properties": {
"reserved": true
}
}
For function app on a Dedicated plan, you must set the serverFarmId
property on the app so that it points to the resource ID of the plan. Make sure that the function app has a dependsOn
setting that also references the plan.
On App Service plan, you should enable the "alwaysOn": true
setting under site config so that your function app runs correctly. On an App Service plan, the functions runtime goes idle after a few minutes of inactivity, so only HTTP triggers will "wake up" your functions.
The WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
and WEBSITE_CONTENTSHARE
settings aren't supported on Dedicated plan.
For a sample Azure Resource Manager template, see Azure Function App Hosted on Dedicated Plan.
The settings required by a function app running in Dedicated plan differ between Windows and Linux.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"alwaysOn": true,
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
}
]
}
}
}
The function app must have set "kind": "functionapp,linux"
, and it must have set property "reserved": true
. Linux apps should also include a linuxFxVersion
property under siteConfig. If you are just deploying code, the value for this is determined by your desired runtime stack in the format of runtime|runtimeVersion. Examples of linuxFxVersion
property include: python|3.7
, node|14
and dotnet|3.1
.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp,linux",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
],
"properties": {
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"alwaysOn": true,
"linuxFxVersion": "node|14",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
}
]
}
}
}
If you are deploying a custom container image, you must specify it with linuxFxVersion
and include configuration that allows your image to be pulled, as in Web App for Containers. Also, set WEBSITES_ENABLE_APP_SERVICE_STORAGE
to false
, since your app content is provided in the container itself:
{
"apiVersion": "2016-03-01",
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"location": "[resourceGroup().location]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "DOCKER_REGISTRY_SERVER_URL",
"value": "[parameters('dockerRegistryUrl')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_USERNAME",
"value": "[parameters('dockerRegistryUsername')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_PASSWORD",
"value": "[parameters('dockerRegistryPassword')]"
},
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"value": "false"
}
],
"linuxFxVersion": "DOCKER|myacr.azurecr.io/myimage:mytag"
}
}
}
Azure Functions can be deployed to Azure Arc-enabled Kubernetes. This process largely follows deploying to an App Service plan, with a few differences to note.
To create the app and plan resources, you must have already created an App Service Kubernetes environment for an Azure Arc-enabled Kubernetes cluster. These examples assume you have the resource ID of the custom location and App Service Kubernetes environment that you are deploying to. For most templates, you can supply these as parameters.
{
"parameters": {
"kubeEnvironmentId" : {
"type": "string"
},
"customLocationId" : {
"type": "string"
}
}
}
Both sites and plans must reference the custom location through an extendedLocation
field. This block sits outside of properties
, peer to kind
and location
:
{
"extendedLocation": {
"type": "customlocation",
"name": "[parameters('customLocationId')]"
},
}
The plan resource should use the Kubernetes (K1) SKU, and its kind
field should be "linux,kubernetes". Within properties
, reserved
should be "true", and kubeEnvironmentProfile.id
should be set to the App Service Kubernetes environment resource ID. An example plan might look like the following:
{
"type": "Microsoft.Web/serverfarms",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"apiVersion": "2020-12-01",
"kind": "linux,kubernetes",
"sku": {
"name": "K1",
"tier": "Kubernetes"
},
"extendedLocation": {
"type": "customlocation",
"name": "[parameters('customLocationId')]"
},
"properties": {
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"workerSizeId": "0",
"numberOfWorkers": "1",
"kubeEnvironmentProfile": {
"id": "[parameters('kubeEnvironmentId')]"
},
"reserved": true
}
}
The function app resource should have its kind
field set to "functionapp,linux,kubernetes" or "functionapp,linux,kubernetes,container" depending on if you intend to deploy via code or container. An example function app might look like the following:
{
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"name": "[variables('appName')]",
"kind": "kubernetes,functionapp,linux,container",
"location": "[parameters('location')]",
"extendedLocation": {
"type": "customlocation",
"name": "[parameters('customLocationId')]"
},
"dependsOn": [
"[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[variables('hostingPlanId')]"
],
"properties": {
"serverFarmId": "[variables('hostingPlanId')]",
"siteConfig": {
"linuxFxVersion": "DOCKER|mcr.microsoft.com/azure-functions/dotnet:3.0-appservice-quickstart",
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2015-05-01').InstrumentationKey]"
}
],
"alwaysOn": true
}
}
}
A function app has many child resources that you can use in your deployment, including app settings and source control options. You also might choose to remove the sourcecontrols child resource, and use a different deployment option instead.
Important
To successfully deploy your application by using Azure Resource Manager, it's important to understand how resources are deployed in Azure. In the following example, top-level configurations are applied by using siteConfig. It's important to set these configurations at a top level, because they convey information to the Functions runtime and deployment engine. Top-level information is required before the child sourcecontrols/web resource is applied. Although it's possible to configure these settings in the child-level config/appSettings resource, in some cases your function app must be deployed before config/appSettings is applied. For example, when you are using functions with Logic Apps, your functions are a dependency of another resource.
{
"apiVersion": "2015-08-01",
"name": "[parameters('appName')]",
"type": "Microsoft.Web/sites",
"kind": "functionapp",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.Web/serverfarms', parameters('appName'))]"
],
"properties": {
"serverFarmId": "[variables('appServicePlanName')]",
"siteConfig": {
"alwaysOn": true,
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "Project",
"value": "src"
}
]
}
},
"resources": [
{
"apiVersion": "2015-08-01",
"name": "appsettings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]",
"[resourceId('Microsoft.Web/Sites/sourcecontrols', parameters('appName'), 'web')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]",
"AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2019-06-01').keys[0].value)]",
"FUNCTIONS_EXTENSION_VERSION": "~3",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"Project": "src"
}
},
{
"apiVersion": "2015-08-01",
"name": "web",
"type": "sourcecontrols",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/', parameters('appName'))]"
],
"properties": {
"RepoUrl": "[parameters('sourceCodeRepositoryURL')]",
"branch": "[parameters('sourceCodeBranch')]",
"IsManualIntegration": "[parameters('sourceCodeManualIntegration')]"
}
}
]
}
Tip
This template uses the Project app settings value, which sets the base directory in which the Functions deployment engine (Kudu) looks for deployable code. In our repository, our functions are in a subfolder of the src folder. So, in the preceding example, we set the app settings value to src
. If your functions are in the root of your repository, or if you are not deploying from source control, you can remove this app settings value.
You can use any of the following ways to deploy your template:
Replace <url-encoded-path-to-azuredeploy-json>
with a URL-encoded version of the raw path of your azuredeploy.json
file in GitHub.
Here is an example that uses markdown:
[](https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>)
Here is an example that uses HTML:
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>" target="_blank"><img src="https://azuredeploy.net/deploybutton.png"></a>
The following PowerShell commands create a resource group and deploy a template that creates a function app with its required resources. To run locally, you must have Azure PowerShell installed. Run Connect-AzAccount
to sign in.
# Register Resource Providers if they're not already registered
Register-AzResourceProvider -ProviderNamespace "microsoft.web"
Register-AzResourceProvider -ProviderNamespace "microsoft.storage"
# Create a resource group for the function app
New-AzResourceGroup -Name "MyResourceGroup" -Location 'West Europe'
# Create the parameters for the file, which for this template is the function app name.
$TemplateParams = @{"appName" = "<function-app-name>"}
# Deploy the template
New-AzResourceGroupDeployment -ResourceGroupName "MyResourceGroup" -TemplateFile template.json -TemplateParameterObject $TemplateParams -Verbose
To test out this deployment, you can use a template like this one that creates a function app on Windows in a Consumption plan. Replace <function-app-name>
with a unique name for your function app.
Learn more about how to develop and configure Azure Functions.