I explain how to do it for Linux Premium Plan.
Compared with Linux Premium, Linux AppService is much easier. I'll add some resources for the best practices for the ARM template.
You can find a sample in here.
serverfarms
For the AppService Plan with Linux, kind
as Linux
and reserved
as true
is the point.
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[parameters('hostingPlanName')]",
"location": "[parameters('location')]",
"kind": "Linux",
"sku": {
"tier": "[parameters('sku')]",
"name": "[parameters('skuCode')]"
},
"properties": {
"reserved": true
}
},
Web/sites
kind
as functionapp,linux
, linuxFxVersion
is the point. For more details about the linuxFxVersion
please refer to Deploy Premium Linux Function App with ARM template
For the premium and consumption plan, we DONT 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": {
"linuxFxVersion": "[parameters('linuxFxVersion')]",
"alwaysOn": "[parameters('alwaysOn')]",
"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')]"
}
]
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"clientAffinityEnabled": false
}
},
APPLICATIONINSIGHTS_CONNECTION_STRING
What is that? As you can see, it is the same value. They want to move on CONNECTION_STRING that they can add other key/value info. Currently, we need to specify both.
key | value (sample) |
---|---|
APPINSIGHTS_INSTRUMENTATIONKEY | 96cd2ffe-ef28-4809-b98a-8f1da9da4b5a |
APPLICATIONINSIGHTS_CONNECTION_STRING | InstrumentationKey=96cd2ffe-ef28-4809-b98a-8f1da9da4b5a |
NOTE: The key is removed already.
ARM template resources
Understand the structure
I didn't know the functions
section. It means, we can write custom functions with using existing build-in functions.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "",
"apiProfile": "",
"parameters": { },
"variables": { },
"functions": [ ],
"resources": [ ],
"outputs": { }
}
name | required | description | sample |
---|---|---|---|
$schema | Yes | Location of the JSON schema file that describes the version of the template language. The version number you use depends on the scope of the deployment and your JSON editor. | If you're using VS Code with the Azure Resource Manager tools extension, use the latest version https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#
|
contentVersion | Yes | Version of the template | 1.0.0.0 |
apiProfile | No | An API version that serves as a collection of API versions for resource types. Use this value to avoid having to specify API versions for each resource in the template. For more details refer to Track versions using API profiles | 2018–03-01-hybrid |
parameters | No | Values that are provided when deployment is executed to customize resource deployment. | See the sample |
variables | No | Values that are used in the template. Usually modify it from parameters or default values. | Variables |
functions | No | User-defined functions that are available within the template. | functions |
resources | Yes | Resource types that are deployed or updated in a resource group or subscription. | resources |
outputs | No | Values that are returned after deployment. It is useful to get ConnectionString for example |
output |
How to set the default value to the parameter?
defaultValue
works. Also you can add description
on the metadata
section. It helps users to understand the meaning.
"linuxFxVersion": {
"type": "string",
"defaultValue": "Java|8",
"metadata": {
"description": "linuxFxVersion that specify the language runtime for linux. (Java|8) for example"
}
},
How to generate random characters
I want to add suffix for the storage account name. If you delete a storage account, then you want to use the same name, it won't work for a while (around 2 hours). Some resources requires random values. Terraform provide it, how about ARM template?
There is. However, it looks not great. It is uniquestring it says
The returned value isn't a random string, but rather the result of a hash function. The returned value is 13 characters long. It isn't globally unique.
I eventually, create the random string with bash script. I frequently reference this repo. DevOps Openhack Proctor Repository. This repo is like a treasure box of DevOps practices.
randomChar() {
s=abcdefghijklmnopqrstuvxwyz0123456789
p=$(( $RANDOM % 36))
echo -n ${s:$p:1}
}
randomNum() {
echo -n $(( $RANDOM % 10 ))
}
postfix="$(randomChar;randomChar;randomChar;randomNum;)"
How to deploy the template from Azure CLI
Create a resource group with az group create
then use az deployment group create
. I avoid the parameter files. I wanted to create resources with some base string. e.g. tsuyoshi
then I'd like to post fix these. tsuyoshi012234sed
, tsuyoshi-app
, tsuyoshi-plan
or something like that. It is enough through the parameters. Also, want to avoid the confusion when we both use parameter files and parameter.
if [ `az group exists -n $resourceGroup -o tsv` == false ]; then
echo "Resource group with name" $resourceGroup "could not be found. Creating new resource group.."
set -e
(
set -x
echo "0-Provision Resource Group (az group create --name $resourceGroup --location $location)"
az group create --name $resourceGroup --location "$location"
)
else
echo "Using existing resource group..."
fi
echo "SubscriptionId : ${subscriptionId}"
echo "Deploying Function App..."
echo "1-Provision FunctionApp (az group deployment create --name ${deploymentName} --resource-group $resourceGroupName --template-file $templateFile --parameters subscriptionId=$subscriptionId serverFarmResourceGroup=$resourceGroup name=$functionAppName location="${location}" hostingPlanName=$hostingPlanName storageAccountName=$storageAccountName appInsightsName=$appInsightsName linuxFxVersion=$linuxFxVersion functionWorkerRuntime=$functionWorkerRuntime)"
az deployment group create \
--name ${deploymentName} \
--resource-group $resourceGroup \
--template-file $templateFile \
--parameters subscriptionId=$subscriptionId serverFarmResourceGroup=$resourceGroup name=$functionAppName location="${location}" hostingPlanName=$hostingPlanName storageAccountName=$storageAccountName appInsightsName=$appInsightsName linuxFxVersion="$linuxFxVersion" functionWorkerRuntime=$functionWorkerRuntime
Top comments (0)