8
votes

I've created a new Function App in Azure. I picked a consumption plan for the App Service Plan.

Once the app is created I now have a new App Service Plan called "WestEuropePlan" In my resource group.

Next thing. IT department says "WestEuropePlan" is not the correct naming convention for App Service Plans.

What are my options. When creating the Function App Im not allowed to pick or name an existing plan when using consumption based plans.

I cannot rename my autogenerated plan.

I cannot manually create a consumption based plan previous to creating the Function App.

What do i do? Is my only option to not use Consumption based plans and instead create a normal app service plan that I can name myself?

Is there something I can do from azure CLI or using ARM templates?

4

4 Answers

9
votes

You can create a Azure Function on Consumption plan with your choice of name for consumption plan using ARM Template. Below is the sample template and parameter file:

Templatefile.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appName": {
      "type": "string",
      "metadata": {
        "description": "The name of the function app that you wish to create."
      }
    },
    "storageAccountType": {
      "type": "string",
      "defaultValue": "Standard_LRS",
      "allowedValues": ["Standard_LRS", "Standard_GRS", "Standard_RAGRS"],
      "metadata": {
        "description": "Storage Account type"
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "runtime": {
      "type": "string",
      "defaultValue": "node",
      "allowedValues": ["node", "dotnet", "java"],
      "metadata": {
        "description": "The language worker runtime to load in the function app."
      }
    }
  },
  "variables": {
    "functionAppName": "[parameters('appName')]",
    "hostingPlanName": "[parameters('appName')]",
    "applicationInsightsName": "[parameters('appName')]",
    "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'azfunctions')]",
    "storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
    "functionWorkerRuntime": "[parameters('runtime')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[variables('storageAccountName')]",
      "apiVersion": "2016-12-01",
      "location": "[parameters('location')]",
      "kind": "Storage",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      }
    },
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2015-04-01",
      "name": "[variables('hostingPlanName')]",
      "location": "[parameters('location')]",
      "properties": {
        "name": "[variables('hostingPlanName')]",
        "computeMode": "Dynamic",
        "sku": "Dynamic"
      }
    },
    {
      "apiVersion": "2015-08-01",
      "type": "Microsoft.Web/sites",
      "name": "[variables('functionAppName')]",
      "location": "[parameters('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": "AzureWebJobsDashboard",
              "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
            },
            {
              "name": "AzureWebJobsStorage",
              "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
            },
            {
              "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
              "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
            },
            {
              "name": "WEBSITE_CONTENTSHARE",
              "value": "[toLower(variables('functionAppName'))]"
            },
            {
              "name": "FUNCTIONS_EXTENSION_VERSION",
              "value": "~2"
            },
            {
              "name": "WEBSITE_NODE_DEFAULT_VERSION",
              "value": "8.11.1"
            },
            {
              "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
              "value": "[reference(resourceId('microsoft.insights/components/', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
            },
            {
              "name": "FUNCTIONS_WORKER_RUNTIME",
              "value": "[variables('functionWorkerRuntime')]"
            }
          ]
        }
      }
    },
    {
      "apiVersion": "2018-05-01-preview",
      "name": "[variables('applicationInsightsName')]",
      "type": "microsoft.insights/components",
      "location": "East US",
      "tags": {
        "[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('applicationInsightsName'))]": "Resource"
      },
      "properties": {
        "ApplicationId": "[variables('applicationInsightsName')]",
        "Request_Source": "IbizaWebAppExtensionCreate"
      }
    }
  ]
}

Reference: https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic

5
votes

Above answers will help if you are doing using Azure CLI, if you want to do via Portal itself, you can do as follows,

  1. On the Azure function Review + create step, there is an option to Download the template for automation and you can click on it. Then the Template will be displayed for downloading.
  2. Now click on Deploy
  3. Now you can easily change the Hosting Plan Name, agree to T&Cs and click on Purchase.

More Information: http://jaliyaudagedara.blogspot.com/2020/08/azure-functions-consumption-plan-custom.html

1
votes

You can create from this ARM Template. No app insights and it'll ask appName, hostingPlanName, storageAccountName, storageAccountType, location and runtime

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "appName": {
        "type": "string",
        "metadata": {
            "description": "The name of the function app that you wish to create."
        }
    },
     "hostingPlanName": {
        "type": "string",
        "metadata": {
            "description": "The name of the consumption plan that you wish to create."
        }
    },
    "storageAccountName": {
        "type": "string",
        "metadata": {
            "description": "The name of the storage account name that you wish to create."
        }
    },
    "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_LRS",
        "allowedValues": [
            "Standard_LRS",
            "Standard_GRS",
            "Standard_RAGRS"
        ],
        "metadata": {
            "description": "Storage Account type"
        }
    },
    "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]",
        "metadata": {
            "description": "Location for all resources."
        }
    },
    "runtime": {
        "type": "string",
        "defaultValue": "node",
        "allowedValues": [
            "node",
            "dotnet",
            "java"
        ],
        "metadata": {
            "description": "The language worker runtime to load in the function app."
        }
    }
},
"variables": {
    "functionAppName": "[parameters('appName')]",
    "hostingPlanName": "[parameters('hostingPlanName')]",
    "storageAccountName": "[parameters('storageAccountName')]",
    "storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
    "functionWorkerRuntime": "[parameters('runtime')]"
},
"resources": [
    {
        "type": "Microsoft.Storage/storageAccounts",
        "name": "[variables('storageAccountName')]",
        "apiVersion": "2016-12-01",
        "location": "[parameters('location')]",
        "kind": "Storage",
        "sku": {
            "name": "[parameters('storageAccountType')]"
        }
    },
    {
        "type": "Microsoft.Web/serverfarms",
        "apiVersion": "2018-02-01",
        "name": "[variables('hostingPlanName')]",
        "location": "[parameters('location')]",
        "sku": {
            "name": "Y1",
            "tier": "Dynamic"
        },
        "properties": {
            "name": "[variables('hostingPlanName')]",
            "computeMode": "Dynamic"
        }
    },
    {
        "apiVersion": "2015-08-01",
        "type": "Microsoft.Web/sites",
        "name": "[variables('functionAppName')]",
        "location": "[parameters('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": "AzureWebJobsDashboard",
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
                    },
                    {
                        "name": "AzureWebJobsStorage",
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
                    },
                    {
                        "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
                    },
                    {
                        "name": "WEBSITE_CONTENTSHARE",
                        "value": "[toLower(variables('functionAppName'))]"
                    },
                    {
                        "name": "FUNCTIONS_EXTENSION_VERSION",
                        "value": "~2"
                    },
                    {
                        "name": "WEBSITE_NODE_DEFAULT_VERSION",
                        "value": "8.11.1"
                    },
                    {
                        "name": "FUNCTIONS_WORKER_RUNTIME",
                        "value": "[variables('functionWorkerRuntime')]"
                    }
                ]
            }
        }
    }
]

}

0
votes

I recommend you to use Az PowerShell or AzureCLI to perform the naming of your Function App Consumption Plan, it's easier to maintain than ARM Template.

The trick is that you need to create a B1 plan first (so with your custom name) then change some settings on your FunctionApp to fit the ConsumptionPlan restriction (i.e.: AlwaysOn=$false), then you can update/change your App Service Plan B1 to a Consumption Plan (called Y1)

Please find my script in PowerShell to create a Linux Consumption Plan : (For Windows plan, you can remove "kind" and "properties.reserved=true" in the variable $fullObject, replace "linux" by "windows" on the variable $os_type and remove $my_runtimeVersion variable and change $my_runtime variable from "python" to "dotnet" (or remove it as by default it's dotnet))

# Function App configuration object - Need to be a Basic Tier first as you cannot directly create a consumption plan
$fullObject = @{
   location = "West Europe"
   sku = @{
        name = "B1"
        tier = "Basic"
   }
   kind = "linux"
   properties = @{
        reserved = $true
   }
}

$resourceGroupName = "rg-my-test"
$serverFarmName = "aspl-my-test"
$storageName = "stg-my-test"
$functionAppName = "fa-my-test"
$my_runtime = "python"
$my_runtimeVersion = "3.8"
$os_type = "linux"

Write-Host "Step 1: CREATING APP SERVICE PLAN B1:Basic named [$serverFarmName]"
# Create a server farm which will host the function app in the resource group specified
New-AzResource -ResourceGroupName $resourceGroupName -ResourceType "Microsoft.Web/serverfarms" -Name $serverFarmName -IsFullObject -PropertyObject $fullObject -Force
Write-Host "Step 1: Done"

Write-Host "Step 2: CREATING STORAGE ACCOUNT named [$storageName]"
# Create a storage account which will contain the Azure Function script
New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageName -Location westeurope -SkuName Standard_LRS
Write-Host "Step 2: Done"

Write-Host "Step 3: CREATING FUNCTION APP named [$functionAppName]"
# Create a function app in the server farm previously created
New-AzFunctionApp -ResourceGroupName $resourceGroupName -Name $functionAppName -PlanName $serverFarmName -StorageAccount $storageName -Runtime $my_runtime -FunctionsVersion 3 -OSType $os_type -RuntimeVersion $my_runtimeVersion -DisableApplicationInsights
Write-Host "Step 3: Done"

Write-Host "Step 4a: GET FUNCTION APP as an PSObject"
$funcApp = Get-AzResource -ResourceType 'microsoft.web/sites' -ResourceGroupName $resourceGroupName -ResourceName $functionAppName
Write-Host "Step 4a: Done"

Write-Host "Step 4b: SET FUNCTION APP settings"
Write-Host "  siteConfig:"
Write-Host "    AlwaysOn: false"
Write-Host "    FtpsState: Disabled"
Write-Host "    MinTlsVersion: 1.2"
Write-Host "    Http20Enabled: true"
Write-Host "  HttpsOnly: true"
$fullObject = @{
   siteConfig = @{
      AlwaysOn = $false
      FtpsState = "Disabled"
      MinTlsVersion = "1.2"
      Http20Enabled = $true
   }
   HttpsOnly = $true
}

$funcApp | Set-AzResource -PropertyObject $fullObject -Force
Write-Host "Step 4b: Done"

Write-Host "Step 5: Set App Service Plan to Dynamic Consumption Plan"
Set-AzAppServicePlan -Name $serverFarmName -ResourceGroupName $resourceGroupName -Tier Y1
Write-Host "Step 5: Done"

In Azure CLI, the command to switch the plan to Consumption Plan is:

az appservice plan update --name aspl-my-test --resource-group rg-my-test --set sku.name=Y1