Quickstart: Create and deploy Azure Functions resources from an ARM template

In this article, you use an Azure Resource Manager template (ARM template) to create a function that responds to HTTP requests.

Completing this quickstart incurs a small cost of a few USD cents or less in your Azure account.

An ARM template is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for your project. The template uses declarative syntax. In declarative syntax, you describe your intended deployment without writing the sequence of programming commands to create the deployment.

If your environment meets the prerequisites and you're familiar with using ARM templates, select the Deploy to Azure button. The template will open in the Azure portal.

Deploy to Azure

Prerequisites

Azure account

Before you begin, you must have an Azure account with an active subscription. Create an account for free.

Create a local functions project

This article requires a local functions code project to run on the Azure resources that you create. If you don't first create a project to publish, you won't be able to complete the deployment section of this article.

Choose one of the following tabs, follow the link, and complete the section to create a function app in the language of your choice:

Create your local functions project in your chosen language in Visual Studio Code:

After you've created your project locally, you create the resources required to run your new function in Azure.

Review the template

The template used in this quickstart is from Azure Quickstart Templates.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appName": {
      "type": "string",
      "defaultValue": "[concat('fnapp', uniqueString(resourceGroup().id))]",
      "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."
      }
    },
    "appInsightsLocation": {
      "type": "string",
      "metadata": {
        "description": "Location for Application Insights"
      }
    },
    "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')]",
    "functionWorkerRuntime": "[parameters('runtime')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      },
      "kind": "Storage"
    },
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2020-06-01",
      "name": "[variables('hostingPlanName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Y1",
        "tier": "Dynamic"
      },
      "properties": {
        "name": "[variables('hostingPlanName')]",
        "computeMode": "Dynamic"
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2020-06-01",
      "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": "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(variables('functionAppName'))]"
            },
            {
              "name": "FUNCTIONS_EXTENSION_VERSION",
              "value": "~2"
            },
            {
              "name": "WEBSITE_NODE_DEFAULT_VERSION",
              "value": "~10"
            },
            {
              "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
              "value": "[reference(resourceId('microsoft.insights/components', variables('applicationInsightsName')), '2020-02-02-preview').InstrumentationKey]"
            },
            {
              "name": "FUNCTIONS_WORKER_RUNTIME",
              "value": "[variables('functionWorkerRuntime')]"
            }
          ]
        }
      }
    },
    {
      "type": "microsoft.insights/components",
      "apiVersion": "2020-02-02-preview",
      "name": "[variables('applicationInsightsName')]",
      "location": "[parameters('appInsightsLocation')]",
      "tags": {
        "[concat('hidden-link:', resourceId('Microsoft.Web/sites', variables('applicationInsightsName')))]": "Resource"
      },
      "properties": {
        "ApplicationId": "[variables('applicationInsightsName')]",
        "Request_Source": "IbizaWebAppExtensionCreate"
      }
    }
  ]
}

The following four Azure resources are created by this template:

Deploy the template

read -p "Enter a resource group name that is used for generating resource names:" resourceGroupName &&
read -p "Enter the location (like 'eastus' or 'northeurope'):" location &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-create-dynamic/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri &&
echo "Press [ENTER] to continue ..." &&
read

Validate the deployment

Next you validate the function app hosting resources you created by publishing your project to Azure and calling the HTTP endpoint of the function.

Publish the function project to Azure

Use the following steps to publish your project to the new Azure resources:

  1. In Visual Studio Code, select F1 to open the command palette. In the command palette, search for and select Azure Functions: Deploy to function app.

  2. If you're not signed in, you're prompted to Sign in to Azure. After you sign in from the browser, go back to Visual Studio Code. If you have multiple subscriptions, Select a subscription that contains your function app.

  3. Select your existing function app in Azure. When you're warned about overwriting all files in the function app, select Deploy to acknowledge the warning and continue.

The project is rebuilt, repackaged, and uploaded to Azure. The existing project is replaced by the new package, and the function app restarts.

In the output, copy the URL of the HTTP trigger. You use this to test your function running in Azure.

Invoke the function on Azure

Paste the URL you copied for the HTTP request into your browser's address bar, make sure that the name query string as ?name=Functions has been appended to the end of this URL, and then execute the request.

You should see a response like:

Hello Functions!

Clean up resources

If you continue to the next step and add an Azure Storage queue output binding, keep all your resources in place as you'll build on what you've already done.

Otherwise, use the following command to delete the resource group and all its contained resources to avoid incurring further costs.

az group delete --name <RESOURCE_GROUP_NAME>

Replace <RESOURCE_GROUP_NAME> with the name of your resource group.

Next steps

Now that you've publish your first function, learn more by adding an output binding to your function.