Udostępnij za pomocą


Szybki start: tworzenie i wdrażanie zasobów usługi Azure Functions na podstawie szablonu usługi ARM

W tym artykule użyjesz szablonu usługi Azure Resource Manager (szablonu usługi ARM) do utworzenia aplikacji funkcji w planie Flex Consumption na platformie Azure wraz z wymaganymi zasobami platformy Azure. Aplikacja funkcji udostępnia kontekst wykonywania bezserwerowego na potrzeby wykonywania kodu funkcji. Aplikacja używa identyfikatora Entra firmy Microsoft z tożsamościami zarządzanymi w celu nawiązania połączenia z innymi zasobami platformy Azure.

Ukończenie tego szybkiego startu wiąże się z naliczeniem niewielkiej opłaty wynoszącej kilka centów USD lub mniej na koncie Azure.

Szablon usługi Azure Resource Manager to plik JavaScript Object Notation (JSON), który definiuje infrastrukturę i konfigurację projektu. Szablon używa składni deklaratywnej. Możesz opisać zamierzone wdrożenie bez konieczności pisania sekwencji poleceń programowania w celu utworzenia wdrożenia.

Jeśli środowisko spełnia wymagania i znasz szablony ARM, wybierz przycisk Wdróż na platformie Azure. Szablon zostanie otwarty w witrynie Azure Portal.

Przycisk wdrażania szablonu usługi Resource Manager na platformie Azure.

Po utworzeniu aplikacji funkcji możesz wdrożyć kod projektu usługi Azure Functions w tej aplikacji. Ostatni krok wdrażania kodu leży poza zakresem tego artykułu startowego.

Prerequisites

Konto platformy Azure

Przed rozpoczęciem musisz mieć konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.

Przegląd szablonu

Szablon użyty w tym szybkim starcie pochodzi z szablonów szybkiego startu platformy Azure.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.33.93.31351",
      "templateHash": "7223343042960867068"
    }
  },
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "minLength": 1,
      "metadata": {
        "description": "Primary region for all Azure resources."
      }
    },
    "functionAppRuntime": {
      "type": "string",
      "defaultValue": "dotnet-isolated",
      "allowedValues": [
        "dotnet-isolated",
        "python",
        "java",
        "node",
        "powerShell"
      ],
      "metadata": {
        "description": "Language runtime used by the function app."
      }
    },
    "functionAppRuntimeVersion": {
      "type": "string",
      "defaultValue": "8.0",
      "allowedValues": [
        "3.10",
        "3.11",
        "7.4",
        "8.0",
        "9.0",
        "10",
        "11",
        "17",
        "20"
      ],
      "metadata": {
        "description": "Target language version used by the function app."
      }
    },
    "maximumInstanceCount": {
      "type": "int",
      "defaultValue": 100,
      "minValue": 40,
      "maxValue": 1000,
      "metadata": {
        "description": "The maximum scale-out instance count limit for the app."
      }
    },
    "instanceMemoryMB": {
      "type": "int",
      "defaultValue": 2048,
      "allowedValues": [
        2048,
        4096
      ],
      "metadata": {
        "description": "The memory size of instances used by the app."
      }
    },
    "resourceToken": {
      "type": "string",
      "defaultValue": "[toLower(uniqueString(subscription().id, parameters('location')))]",
      "minLength": 3,
      "metadata": {
        "description": "A unique token used for resource name generation."
      }
    },
    "appName": {
      "type": "string",
      "defaultValue": "[format('func-{0}', parameters('resourceToken'))]",
      "metadata": {
        "description": "A globally unigue name for your deployed function app."
      }
    }
  },
  "variables": {
    "deploymentStorageContainerName": "[format('app-package-{0}-{1}', take(parameters('appName'), 32), take(parameters('resourceToken'), 7))]",
    "storageAccountAllowSharedKeyAccess": false,
    "storageBlobDataOwnerRoleId": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b",
    "storageBlobDataContributorRoleId": "ba92f5b4-2d11-453d-a403-e96b0029c9fe",
    "storageQueueDataContributorId": "974c5e8b-45b9-4653-ba55-5f855dd0fb88",
    "storageTableDataContributorId": "0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3",
    "monitoringMetricsPublisherId": "3913510d-42f4-4e42-8a64-420c390055eb"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
      "apiVersion": "2023-05-01",
      "name": "[format('{0}/{1}/{2}', format('st{0}', parameters('resourceToken')), 'default', variables('deploymentStorageContainerName'))]",
      "properties": {
        "publicAccess": "None"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts/blobServices', format('st{0}', parameters('resourceToken')), 'default')]"
      ]
    },
    {
      "type": "Microsoft.Storage/storageAccounts/blobServices",
      "apiVersion": "2023-05-01",
      "name": "[format('{0}/{1}', format('st{0}', parameters('resourceToken')), 'default')]",
      "properties": {
        "deleteRetentionPolicy": {}
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Web/sites/config",
      "apiVersion": "2024-04-01",
      "name": "[format('{0}/{1}', parameters('appName'), 'appsettings')]",
      "properties": {
        "AzureWebJobsStorage__accountName": "[format('st{0}', parameters('resourceToken'))]",
        "AzureWebJobsStorage__credential": "managedidentity",
        "AzureWebJobsStorage__clientId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').clientId]",
        "APPLICATIONINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components', format('appi-{0}', parameters('resourceToken'))), '2020-02-02').InstrumentationKey]",
        "APPLICATIONINSIGHTS_AUTHENTICATION_STRING": "[format('ClientId={0};Authorization=AAD', reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').clientId)]"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Insights/components', format('appi-{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.Web/sites', parameters('appName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.OperationalInsights/workspaces",
      "apiVersion": "2023-09-01",
      "name": "[format('log-{0}', parameters('resourceToken'))]",
      "location": "[parameters('location')]",
      "properties": {
        "retentionInDays": 30,
        "features": {
          "searchVersion": 1
        },
        "sku": {
          "name": "PerGB2018"
        }
      }
    },
    {
      "type": "Microsoft.Insights/components",
      "apiVersion": "2020-02-02",
      "name": "[format('appi-{0}', parameters('resourceToken'))]",
      "location": "[parameters('location')]",
      "kind": "web",
      "properties": {
        "Application_Type": "web",
        "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('log-{0}', parameters('resourceToken')))]",
        "DisableLocalAuth": true
      },
      "dependsOn": [
        "[resourceId('Microsoft.OperationalInsights/workspaces', format('log-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-05-01",
      "name": "[format('st{0}', parameters('resourceToken'))]",
      "location": "[parameters('location')]",
      "kind": "StorageV2",
      "sku": {
        "name": "Standard_LRS"
      },
      "properties": {
        "accessTier": "Hot",
        "allowBlobPublicAccess": false,
        "allowSharedKeyAccess": "[variables('storageAccountAllowSharedKeyAccess')]",
        "dnsEndpointType": "Standard",
        "minimumTlsVersion": "TLS1_2",
        "networkAcls": {
          "bypass": "AzureServices",
          "defaultAction": "Allow"
        },
        "publicNetworkAccess": "Enabled"
      }
    },
    {
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
      "apiVersion": "2023-01-31",
      "name": "[format('uai-data-owner-{0}', parameters('resourceToken'))]",
      "location": "[parameters('location')]"
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('st{0}', parameters('resourceToken')))]",
      "name": "[guid(subscription().id, resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken'))), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), 'Storage Blob Data Owner')]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('storageBlobDataOwnerRoleId'))]",
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('st{0}', parameters('resourceToken')))]",
      "name": "[guid(subscription().id, resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken'))), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), 'Storage Blob Data Contributor')]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('storageBlobDataContributorRoleId'))]",
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('st{0}', parameters('resourceToken')))]",
      "name": "[guid(subscription().id, resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken'))), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), 'Storage Queue Data Contributor')]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('storageQueueDataContributorId'))]",
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('st{0}', parameters('resourceToken')))]",
      "name": "[guid(subscription().id, resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken'))), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), 'Storage Table Data Contributor')]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('storageTableDataContributorId'))]",
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Insights/components/{0}', format('appi-{0}', parameters('resourceToken')))]",
      "name": "[guid(subscription().id, resourceId('Microsoft.Insights/components', format('appi-{0}', parameters('resourceToken'))), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), 'Monitoring Metrics Publisher')]",
      "properties": {
        "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('monitoringMetricsPublisherId'))]",
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))), '2023-01-31').principalId]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Insights/components', format('appi-{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    },
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2024-04-01",
      "name": "[format('plan-{0}', parameters('resourceToken'))]",
      "location": "[parameters('location')]",
      "kind": "functionapp",
      "sku": {
        "tier": "FlexConsumption",
        "name": "FC1"
      },
      "properties": {
        "reserved": true
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2024-04-01",
      "name": "[parameters('appName')]",
      "location": "[parameters('location')]",
      "kind": "functionapp,linux",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken'))))]": {}
        }
      },
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', format('plan-{0}', parameters('resourceToken')))]",
        "httpsOnly": true,
        "siteConfig": {
          "minTlsVersion": "1.2"
        },
        "functionAppConfig": {
          "deployment": {
            "storage": {
              "type": "blobContainer",
              "value": "[format('{0}{1}', reference(resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken'))), '2023-05-01').primaryEndpoints.blob, variables('deploymentStorageContainerName'))]",
              "authentication": {
                "type": "UserAssignedIdentity",
                "userAssignedIdentityResourceId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
              }
            }
          },
          "scaleAndConcurrency": {
            "maximumInstanceCount": "[parameters('maximumInstanceCount')]",
            "instanceMemoryMB": "[parameters('instanceMemoryMB')]"
          },
          "runtime": {
            "name": "[parameters('functionAppRuntime')]",
            "version": "[parameters('functionAppRuntimeVersion')]"
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', format('plan-{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.Storage/storageAccounts', format('st{0}', parameters('resourceToken')))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('uai-data-owner-{0}', parameters('resourceToken')))]"
      ]
    }
  ]
}

Ten szablon tworzy te zasoby platformy Azure wymagane przez aplikację funkcji, która bezpiecznie łączy się z usługami platformy Azure:

Zagadnienia dotyczące wdrażania:

  • Konto magazynu służy do przechowywania ważnych danych aplikacji, w tym pakietu wdrażania kodu aplikacji. Wdrożenie to tworzy konto magazynowe, do którego dostęp uzyskuje się za pomocą uwierzytelniania Microsoft Entra ID oraz zarządzanych tożsamości. Dostęp do zasobów jest udzielany zgodnie z zasadą najmniejszych uprawnień.
  • Plik Bicep domyślnie tworzy aplikację w języku C#, która używa platformy .NET 8 w izolowanym procesie. W przypadku innych języków użyj parametrów functionAppRuntime i functionAppRuntimeVersion, aby określić konkretny język i wersję, w której ma być uruchamiana aplikacja. Pamiętaj, aby wybrać język programowania w górnej części artykułu.

Wdrażanie szablonu

Te skrypty zostały zaprojektowane pod kątem i przetestowane w usłudze Azure Cloud Shell. Wybierz pozycję Wypróbuj , aby otworzyć wystąpienie usługi Cloud Shell bezpośrednio w przeglądarce. Po wyświetleniu monitu wprowadź nazwę regionu obsługującego plan Flex Consumption, na przykład eastus lub northeurope.

read -p "Enter a supported Azure region: " location &&
resourceGroupName=exampleRG &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-flex-managed-identities/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri --parameters functionAppRuntime=dotnet-isolated functionAppRuntimeVersion=8.0 &&
echo "Press [ENTER] to continue ..." &&
read
read -p "Enter a supported Azure region: " location &&
resourceGroupName=exampleRG &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-flex-managed-identities/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri --parameters functionAppRuntime=java functionAppRuntimeVersion=17 &&
echo "Press [ENTER] to continue ..." &&
read
read -p "Enter a supported Azure region: " location &&
resourceGroupName=exampleRG &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-flex-managed-identities/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri --parameters functionAppRuntime=node functionAppRuntimeVersion=20 &&
echo "Press [ENTER] to continue ..." &&
read
read -p "Enter a supported Azure region: " location &&
resourceGroupName=exampleRG &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-flex-managed-identities/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri --parameters functionAppRuntime=python functionAppRuntimeVersion=3.11 &&
echo "Press [ENTER] to continue ..." &&
read
read -p "Enter a supported Azure region: " location &&
resourceGroupName=exampleRG &&
templateUri="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.web/function-app-flex-managed-identities/azuredeploy.json" &&
az group create --name $resourceGroupName --location "$location" &&
az deployment group create --resource-group $resourceGroupName --template-uri  $templateUri --parameters functionAppRuntime=powerShell functionAppRuntimeVersion=7.4 &&
echo "Press [ENTER] to continue ..." &&
read

Po zakończeniu wdrażania powinien zostać wyświetlony komunikat informujący o pomyślnym wdrożeniu.

Odwiedź stronę powitalną aplikacji funkcjonalnej

  1. Użyj danych wyjściowych z poprzedniego kroku weryfikacji, aby pobrać unikatową nazwę utworzoną dla aplikacji funkcji.

  2. Otwórz przeglądarkę i wprowadź następujący adres URL: <https://< appName.azurewebsites.net>. Upewnij się, że zastąpisz <\appName> unikalną nazwą stworzoną dla swojej aplikacji funkcji.

    Podczas odwiedzania adresu URL powinna zostać wyświetlona strona podobna do następującej:

    Strona powitalna aplikacji Function

Uprzątnij zasoby

Po wdrożeniu aplikacji funkcji i powiązanych zasobów na platformie Azure możesz przejść do następnego kroku publikowania kodu projektu w aplikacji. W przeciwnym razie użyj tych poleceń, aby usunąć zasoby, gdy nie są już potrzebne.

az group delete --name exampleRG

Zasoby można również usunąć za pomocą portalu Azure.

Dalsze kroki

Teraz możesz wdrożyć projekt kodu w zasobach aplikacji funkcji utworzonych na platformie Azure.

Możesz utworzyć, zweryfikować i wdrożyć projekt kodu w nowej aplikacji funkcji z następujących środowisk lokalnych: