Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описано, как с помощью Bicep создать приложение функции в плане потребления Flex в Azure, а также его необходимые ресурсы Azure. Приложение-функция предоставляет бессерверный контекст выполнения для выполнения кода функции. Приложение использует Microsoft Entra ID с управляемыми удостоверениями для подключения к другим ресурсам Azure.
Выполнение этого краткого руководства предполагает небольшую дополнительную плату в несколько центов США в учетной записи Azure.
Bicep — это предметно-ориентированный язык (DSL), который использует декларативный синтаксис для развертывания ресурсов Azure. Он обеспечивает краткий синтаксис, надежную безопасность типов и поддержку повторного использования кода. Bicep предлагает лучшие возможности для разработки решений Azure типа "инфраструктура как код".
После создания функционального приложения вы можете развернуть код проекта Функций Azure в этом приложении. Последний шаг развертывания кода выходит за рамки этого быстрого руководства.
Предварительные условия
Учетная запись Azure
Для начала работы вам потребуется учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
Проверка BICEP-файла
Файл Bicep, используемый в этом кратком руководстве, состоит из шаблона быстрого запуска Azure.
/* This Bicep file creates a function app running in a Flex Consumption plan
that connects to Azure Storage by using managed identities with Microsoft Entra ID. */
//********************************************
// Parameters
//********************************************
@description('Primary region for all Azure resources.')
@minLength(1)
param location string = resourceGroup().location
@description('Language runtime used by the function app.')
@allowed(['dotnet-isolated','python','java', 'node', 'powerShell'])
param functionAppRuntime string = 'dotnet-isolated' //Defaults to .NET isolated worker
@description('Target language version used by the function app.')
@allowed(['3.10','3.11', '7.4', '8.0', '9.0', '10', '11', '17', '20'])
param functionAppRuntimeVersion string = '8.0' //Defaults to .NET 8.
@description('The maximum scale-out instance count limit for the app.')
@minValue(40)
@maxValue(1000)
param maximumInstanceCount int = 100
@description('The memory size of instances used by the app.')
@allowed([2048,4096])
param instanceMemoryMB int = 2048
@description('A unique token used for resource name generation.')
@minLength(3)
param resourceToken string = toLower(uniqueString(subscription().id, location))
@description('A globally unigue name for your deployed function app.')
param appName string = 'func-${resourceToken}'
//********************************************
// Variables
//********************************************
// Generates a unique container name for deployments.
var deploymentStorageContainerName = 'app-package-${take(appName, 32)}-${take(resourceToken, 7)}'
// Key access to the storage account is disabled by default
var storageAccountAllowSharedKeyAccess = false
// Define the IDs of the roles we need to assign to our managed identities.
var storageBlobDataOwnerRoleId = 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b'
var storageBlobDataContributorRoleId = 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'
var storageQueueDataContributorId = '974c5e8b-45b9-4653-ba55-5f855dd0fb88'
var storageTableDataContributorId = '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
var monitoringMetricsPublisherId = '3913510d-42f4-4e42-8a64-420c390055eb'
//********************************************
// Azure resources required by your function app.
//********************************************
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: 'log-${resourceToken}'
location: location
properties: any({
retentionInDays: 30
features: {
searchVersion: 1
}
sku: {
name: 'PerGB2018'
}
})
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: 'appi-${resourceToken}'
location: location
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logAnalytics.id
DisableLocalAuth: true
}
}
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: 'st${resourceToken}'
location: location
kind: 'StorageV2'
sku: { name: 'Standard_LRS' }
properties: {
accessTier: 'Hot'
allowBlobPublicAccess: false
allowSharedKeyAccess: storageAccountAllowSharedKeyAccess
dnsEndpointType: 'Standard'
minimumTlsVersion: 'TLS1_2'
networkAcls: {
bypass: 'AzureServices'
defaultAction: 'Allow'
}
publicNetworkAccess: 'Enabled'
}
resource blobServices 'blobServices' = {
name: 'default'
properties: {
deleteRetentionPolicy: {}
}
resource deploymentContainer 'containers' = {
name: deploymentStorageContainerName
properties: {
publicAccess: 'None'
}
}
}
}
resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: 'uai-data-owner-${resourceToken}'
location: location
}
resource roleAssignmentBlobDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, storage.id, userAssignedIdentity.id, 'Storage Blob Data Owner')
scope: storage
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataOwnerRoleId)
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
resource roleAssignmentBlob 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, storage.id, userAssignedIdentity.id, 'Storage Blob Data Contributor')
scope: storage
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributorRoleId)
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
resource roleAssignmentQueueStorage 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, storage.id, userAssignedIdentity.id, 'Storage Queue Data Contributor')
scope: storage
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', storageQueueDataContributorId)
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
resource roleAssignmentTableStorage 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, storage.id, userAssignedIdentity.id, 'Storage Table Data Contributor')
scope: storage
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', storageTableDataContributorId)
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
resource roleAssignmentAppInsights 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, applicationInsights.id, userAssignedIdentity.id, 'Monitoring Metrics Publisher')
scope: applicationInsights
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', monitoringMetricsPublisherId)
principalId: userAssignedIdentity.properties.principalId
principalType: 'ServicePrincipal'
}
}
//********************************************
// Function app and Flex Consumption plan definitions
//********************************************
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: 'plan-${resourceToken}'
location: location
kind: 'functionapp'
sku: {
tier: 'FlexConsumption'
name: 'FC1'
}
properties: {
reserved: true
}
}
resource functionApp 'Microsoft.Web/sites@2024-04-01' = {
name: appName
location: location
kind: 'functionapp,linux'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${userAssignedIdentity.id}':{}
}
}
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
siteConfig: {
minTlsVersion: '1.2'
}
functionAppConfig: {
deployment: {
storage: {
type: 'blobContainer'
value: '${storage.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
authentication: {
type: 'UserAssignedIdentity'
userAssignedIdentityResourceId: userAssignedIdentity.id
}
}
}
scaleAndConcurrency: {
maximumInstanceCount: maximumInstanceCount
instanceMemoryMB: instanceMemoryMB
}
runtime: {
name: functionAppRuntime
version: functionAppRuntimeVersion
}
}
}
resource configAppSettings 'config' = {
name: 'appsettings'
properties: {
AzureWebJobsStorage__accountName: storage.name
AzureWebJobsStorage__credential : 'managedidentity'
AzureWebJobsStorage__clientId: userAssignedIdentity.properties.clientId
APPLICATIONINSIGHTS_INSTRUMENTATIONKEY: applicationInsights.properties.InstrumentationKey
APPLICATIONINSIGHTS_AUTHENTICATION_STRING: 'ClientId=${userAssignedIdentity.properties.clientId};Authorization=AAD'
}
}
}
Этот файл развертывания создает эти ресурсы Azure, необходимые приложению-функции, которое безопасно подключается к службам Azure:
- Microsoft.Web/sites: создает функциональное приложение.
- Microsoft.Web/serverfarms: создает бессерверный план Flex Consumption для размещения вашего приложения.
- Microsoft.Storage/storageAccounts: создает учетную запись хранения Azure, необходимую функциями.
- Microsoft.Insights/components: создает экземпляр Application Insights для мониторинга приложения.
- Microsoft.OperationalInsights/workspaces: создает рабочую область, необходимую Application Insights.
- Microsoft.ManagedIdentity/userAssignedIdentities: создает управляемое удостоверение, назначаемое пользователем, которое используется приложением для проверки подлинности с другими службами Azure с помощью Microsoft Entra.
- Microsoft.Authorization/roleAssignments: создает назначения ролей для управляемого удостоверения, назначаемого пользователем, которые предоставляют приложению минимальные привилегии при подключении к другим службам Azure.
Рекомендации по развертыванию:
- Учетная запись хранения используется для хранения важных данных приложения, включая пакет развертывания кода приложения. Это развертывание создает учетную запись хранения, доступ к которой осуществляется с помощью аутентификации Microsoft Entra ID и управляемых идентификаций. Доступ предоставляется на основе принципа минимальных прав.
- Файл Bicep по умолчанию создает приложение C#, использующее .NET 8 в изолированном процессе. Для других языков используйте параметры
functionAppRuntime
иfunctionAppRuntimeVersion
, чтобы указать конкретный язык и версию, на которой нужно запустить приложение. Убедитесь, что вы выбрали язык программирования в верхней части статьи.
Разверните Bicep-файл
Сохраните файл Bicep с именем main.bicep на локальном компьютере.
Разверните файл Bicep с помощью Azure CLI или Azure PowerShell.
az group create --name exampleRG --location <SUPPORTED_REGION> az deployment group create --resource-group exampleRG --template-file main.bicep --parameters functionAppRuntime=dotnet-isolated functionAppRuntimeVersion=8.0
az group create --name exampleRG --location <SUPPORTED_REGION> az deployment group create --resource-group exampleRG --template-file main.bicep --parameters functionAppRuntime=java functionAppRuntimeVersion=17
az group create --name exampleRG --location <SUPPORTED_REGION> az deployment group create --resource-group exampleRG --template-file main.bicep --parameters functionAppRuntime=node functionAppRuntimeVersion=20
az group create --name exampleRG --location <SUPPORTED_REGION> az deployment group create --resource-group exampleRG --template-file main.bicep --parameters functionAppRuntime=python functionAppRuntimeVersion=3.11
az group create --name exampleRG --location <SUPPORTED_REGION> az deployment group create --resource-group exampleRG --template-file main.bicep --parameters functionAppRuntime=powerShell functionAppRuntimeVersion=7.4
В этом примере замените
<SUPPORTED_REGION>
на регион, который поддерживает план потребления Flex.После завершения развертывания должно отобразиться сообщение о том, что развертывание успешно выполнено.
Проверка развертывания
Используйте Azure CLI или Azure PowerShell для проверки развертывания.
az resource list --resource-group exampleRG
Посетите страницу приветствия функционального приложения
Используйте выходные данные предыдущего шага проверки, чтобы получить уникальное имя, созданное для приложения-функции.
Откройте браузер и введите следующий URL-адрес: <https://< appName.azurewebsites.net>. Обязательно замените <\appName> уникальным именем, созданным для приложения-функции.
При посещении URL-адреса вы увидите следующую страницу:
Очистка ресурсов
Теперь, когда вы развернули приложение-функцию и связанные ресурсы в Azure, можно перейти к следующему шагу публикации кода проекта в приложении. В противном случае используйте эти команды для удаления ресурсов, если они больше не нужны.
az group delete --name exampleRG
Вы также можете удалить ресурсы с помощью портала Azure.
Следующие шаги
Теперь вы можете развернуть проект кода в ресурсах функционального приложения, которые вы создали в Azure.
Вы можете создавать, проверять и развертывать проект кода в новом приложении-функции из следующих локальных сред: