Deploy Premium Linux Function App with ARM template
Tsuyoshi Ushio
Posted on August 13, 2020
I wanted to automate the deployment of the Premium Linux and AppService plan for Java application. I'd like to share what I learned. This repo is the repo I leave the samples.
Premimu Linux
There is an official document however, I can't find Premium Linux configuration.
Serverfarms
targetWorkerCount
and targetWorkerSizeId
are something we can't find on the official documentation. That is int
properties. Important point is, kind
as elastic
and reserved
as true
.
{
"apiVersion": "2018-02-01",
"name": "[parameters('hostingPlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('location')]",
"kind": "elastic",
"tags": {},
"dependsOn": [],
"properties": {
"targetWorkerCount": "[parameters('targetWorkerCount')]",
"targetWorkerSizeId": "[parameters('targetWorkerSizeId')]",
"reserved": true,
"maximumElasticWorkerCount": "[parameters('maximumElasticWorkerCount')]"
},
"sku": {
"tier": "[parameters('sku')]",
"name": "[parameters('skuCode')]"
}
},
We have a several resouces, however, the reference looks the latest.
targetWorkerSizeId
Probably, these meaning.
Small = 0,
Medium = 1,
Large = 2,
D1 = 3,
D2 = 4,
D3 = 5,
SmallV3 = 6,
MediumV3 = 7,
LargeV3 = 8,
NestedSmall = 9,
Web/sites
kind
as functionapp,linux
. For specifying languages, I set FUNCTIONS_WORKER_RUNTIME
as java
, linuxFxVersion
as Java|8
. The linuxFxVersion
requires only on linux. It represents docker images that you found azure functions docker. You can find some possible value in here. It can be specify the generic one like Java|8
but also you can specify specific docker image version like DOCKER|mcr.microsoft.com/azure-functions/python:2.0.13351-python3.6-appservice
. You can find it on azure functions docker repo.
For the premium and consumption plan, we need WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
and WEBSITE_CONTENTSHARE
.
{
"apiVersion": "2018-11-01",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"kind": "functionapp,linux",
"location": "[parameters('location')]",
"tags": {},
"dependsOn": [
"[resourceId('microsoft.insights/components', parameters('appInsightsName'))]",
"[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "[parameters('functionWorkerRuntime')]"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('microsoft.insights/components/', parameters('appInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference(concat('microsoft.insights/components/', parameters('appInsightsName')), '2015-05-01').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[concat(toLower(parameters('name')), '94ed')]"
}
],
"linuxFxVersion": "[parameters('linuxFxVersion')]"
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"clientAffinityEnabled": false
}
},
One of the question is Why do I need both APPINSIGHTS_INSTRUMENTATIONKEY and APPLICATIONINSIGHTS_CONNECTION_STRING in my Azure Function configuration?. You can find the answer on the link.
What did I google it?
Deployed not supported region
{
"Code": "BadRequest",
"Message": "Requested features are not supported in region. Please try another region.",
"Target": null,
"Details": [
{
"Message": "Requested features are not supported in region. Please try another region."
},
{
"Code": "BadRequest"
},
{
"ErrorEntity": {
"ExtendedCode": "59911",
"MessageTemplate": "Requested features are not supported in region. Please try another region.",
"Parameters": [],
"Code": "BadRequest",
"Message": "Requested features are not supported in region. Please try another region."
}
}
],
"Innererror": null
}
These command shows you the location that available to you for each resources.
az provider show --namespace Microsoft.Web | jq ".resourceTypes[] | select(.resourceType == \"serverFarms\") | .locations"
- Products available by region
- az account list-location find locations that you can use.
The serverFarm property has an incorrect value for App Service Plan
The error message was very confusing. However, it was an issue of this part. It was not the serverfarms
resource. I forget to add value to serverFarmResourceGroup
.
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
The way I identify issue is portal. Even if I deploy from my local machine, if you go to portal and see the deployment history, then you can find which resources causes an issue.
Deployment failed. Correlation ID: 95b838bf-3c0d-45f0-9457-0b10c916109f. {
"Code": "BadRequest",
"Message": "The serverFarm property has an incorrect value for App Service Plan. Valid values are a plan name as string or of format subscriptions/subscriptionId/resourceGroups/resourceGroupName/providers/Microsoft.web/serverfarms/planName where the subscription is the same as the site's subscription.",
"Target": null,
serverframs can not found
I encounter the issue. The reason was, the template that I've got from donwload automated script
was wrong. It has a section like this.
"dependsOn": [
"microsoft.insights/components/tsushijava8trace",
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
],
dependsOn
section requires resourceId
function.
"dependsOn": [
"[resourceId('microsoft.insights/components', parameters('appInsightsName'))]",
"[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
Lessons Learned
This time, I have no sample, so I can't identify how we can deploy Premium Functions.
- Deploy Premium Linux functions from portal and download automated script
- Deploy Premium Linux functions from portal and see
Export template
- Offical Doc Automate resource deployment for your function app in Azure Functions
- References Microsoft.Web serverfarms template reference, Microsoft.Web sites/config template reference
When I look back, the best way might be...
- Learn the basic with the official document.
- Deploy Premimu Linux functions from portal and see
Export template
- Understand the meaning of the parameters with Reference
The download automated script
is something I used to use frequently, however, this time, the template does not work. Understand the proper format and check with the Export template
is the truth
.
I hope this helps.
Posted on August 13, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.