Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, usará Bicep para crear una aplicación de funciones en un plan de consumo flexible en Azure, junto con sus recursos de Azure necesarios. La aplicación de funciones proporciona un contexto de ejecución sin servidor para las ejecuciones de código de función. La aplicación usa Microsoft Entra ID con identidades administradas para conectarse a otros recursos de Azure.
Completar este inicio rápido conlleva un pequeño costo de unos pocos centavos de USD o menos en su cuenta de Azure.
Bicep es un lenguaje específico de dominio (DSL) que usa una sintaxis declarativa para implementar recursos de Azure. Proporciona una sintaxis concisa, seguridad de tipos fiable y soporte para la reutilización de código. Bicep ofrece la mejor experiencia de creación para las soluciones de infraestructura como código en Azure.
Después de crear la aplicación de funciones, puede implementar el código del proyecto de Azure Functions en esa aplicación. Un paso de implementación de código final está fuera del ámbito de este artículo de inicio rápido.
Requisitos previos
Cuenta de Azure
Antes de empezar, debe tener una cuenta de Azure con una suscripción activa. Crear una cuenta gratuita.
Revisión del archivo de Bicep
El archivo Bicep utilizado en este inicio rápido procede de una plantilla de inicio rápido de 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'
}
}
}
Este archivo de implementación crea estos recursos de Azure necesarios para una aplicación de funciones que se conecta de forma segura a los servicios de Azure:
- Microsoft.Web/sites: crea su aplicación de funciones.
- Microsoft.Web/serverfarms: crea un plan de hospedaje de Consumo flexible sin servidor para su aplicación.
- Microsoft.Storage/storageAccounts: crea una cuenta de Azure Storage, que requiere Functions.
- Microsoft.Insights/components: crea una instancia de Application Insights para supervisar la aplicación.
- Microsoft.OperationalInsights/workspaces: crea un área de trabajo requerida por Application Insights.
- Microsoft.ManagedIdentity/userAssignedIdentities: crea una identidad administrada asignada por el usuario que usa la aplicación para autenticarse con otros servicios de Azure mediante Microsoft Entra.
- Microsoft.Authorization/roleAssignments: crea asignaciones de roles a la identidad administrada asignada por el usuario, que proporciona a la aplicación acceso con privilegios mínimos al conectarse a otros servicios de Azure.
Consideraciones sobre la implementación:
- La cuenta de almacenamiento se usa para almacenar datos importantes de la aplicación, incluido el paquete de implementación de código de aplicación. Esta implementación crea una cuenta de almacenamiento a la que se accede usando la autenticación de Microsoft Entra ID e identidades administradas. El acceso de identidad se concede por lo menos permisos.
- El archivo Bicep tiene como valor predeterminado la creación de una aplicación de C# que usa .NET 8 en un proceso aislado. Para otros lenguajes, use los parámetros
functionAppRuntime
yfunctionAppRuntimeVersion
para especificar el idioma y la versión específicos en los que se va a ejecutar su aplicación. Asegúrese de seleccionar el lenguaje de programación en la parte superior del artículo.
Implementación del archivo de Bicep
Guarde el archivo de Bicep como main.bicep en el equipo local.
Implemente el archivo de Bicep mediante la CLI de Azure o 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
En este ejemplo, reemplace
<SUPPORTED_REGION>
por una región que admita el plan de consumo Flexible.Una vez finalizada la implementación, debería mostrarse un mensaje indicando que la implementación se realizó correctamente.
Validación de la implementación
Use la CLI de Azure o Azure PowerShell para validar la implementación.
az resource list --resource-group exampleRG
Visite la página principal de la aplicación de funciones
Use la salida del paso de validación anterior para recuperar el nombre único creado para la aplicación de funciones.
Abra un explorador y escriba la siguiente dirección URL: <https://< nombreAplicación.azurewebsites.net>. Asegúrese de reemplazar <\nombreAplicación> por el nombre único creado para la aplicación de funciones.
Al visitar la dirección URL, debería ver una página similar a la siguiente:
Limpieza de recursos
Ahora que ha implementado una aplicación de función y los recursos relacionados en Azure, puede continuar con el siguiente paso de publicación del código del proyecto en su aplicación. De lo contrario, use estos comandos para eliminar los recursos, cuando ya no los necesite.
az group delete --name exampleRG
También puede quitar recursos mediante Azure Portal.
Siguientes pasos
Ahora puede implementar un proyecto de código en los recursos de la aplicación de funciones que creó en Azure.
Puede crear, comprobar e implementar un proyecto de código en la nueva aplicación de funciones desde estos entornos locales: