Compartir vía


Automatización de la implementación de recursos para una aplicación de función en Azure Functions

Puede usar un archivo de Bicep o una plantilla de Azure Resource Manager (ARM) para automatizar el proceso de implementación de la aplicación de funciones. Durante la implementación, puede usar los recursos de Azure existentes o crear otros nuevos. La ayuda de Automation es usted con estos escenarios:

  • Integración de las implementaciones de recursos con el código fuente en Azure Pipelines e implementaciones basadas en Acciones de GitHub.
  • Restaurar una aplicación de funciones y recursos relacionados desde una copia de seguridad.
  • Implementación de una topología de aplicación varias veces.

En este artículo se muestra cómo automatizar la creación de recursos y la implementación para Azure Functions. En función de los desencadenadores y enlaces usados por las funciones, es posible que tenga que implementar otros recursos, que están fuera del ámbito de este artículo.

El código de plantilla necesario depende de las opciones de hospedaje deseadas para la aplicación de funciones. En este artículo se admiten las siguientes opciones de hospedaje:

Opción de hospedaje Tipo de implementación Para obtener más información, consulte...
Azure Functions Consumption plan (Plan de consumo de Azure Functions) Solo código Plan de consumo
Plan de Consumo flexible de Azure Functions Solo código Plan de consumo flexible
Plan Elastic Premium de Azure Functions Código | Contenedor Plan Premium
Plan dedicado de Azure Functions (App Service) Código | Contenedor Plan dedicado
Azure Container Apps Solo el contenedor Container Apps que hospeda Azure Functions
Azure Arc Código | Contenedor App Service, Functions y Logic Apps en Azure Arc (versión preliminar)

Al usar este artículo, tenga en cuenta estas consideraciones:

  • Los ejemplos se muestran como secciones individuales para recursos específicos.

Recursos necesarios

Debe crear o configurar estos recursos para una implementación hospedada en Azure Functions:

Resource Requisito Referencia de sintaxis y propiedades
Una cuenta de almacenamiento. Obligatorio Microsoft.Storage/storageAccounts
Un componente de Application Insights Recomendado Microsoft.Insights/components*
Un Plan de hospedaje Obligatorio Microsoft.Web/serverfarms
Una aplicación de funciones Obligatorio Microsoft.Web/sites

Debe crear o configurar estos recursos para una implementación hospedada en Azure Functions:

Resource Requisito Referencia de sintaxis y propiedades
Una cuenta de almacenamiento. Obligatorio Microsoft.Storage/storageAccounts
Un componente de Application Insights Recomendado Microsoft.Insights/components*
Una aplicación de funciones Obligatorio Microsoft.Web/sites

Normalmente, una implementación hospedada en Azure Container Apps consta de estos recursos:

Resource Requisito Referencia de sintaxis y propiedades
Una cuenta de almacenamiento. Obligatorio Microsoft.Storage/storageAccounts
Un componente de Application Insights Recomendado Microsoft.Insights/components*
Un entorno administrado Obligatorio Microsoft.App/managedEnvironments
Una aplicación de funciones Obligatorio Microsoft.Web/sites

Normalmente, una implementación hospedada en Azure Arc consta de estos recursos:

Resource Requisito Referencia de sintaxis y propiedades
Una cuenta de almacenamiento. Obligatorio Microsoft.Storage/storageAccounts
Un componente de Application Insights Recomendado Microsoft.Insights/components1
Un Entorno de Kubernetes de App Service Obligatorio Microsoft.ExtendedLocation/customLocations
Una aplicación de funciones Obligatorio Microsoft.Web/sites

*Si aún no tiene un área de trabajo de Log Analytics que puede usar la instancia de Application Insights, también debe crear este recurso.

Al implementar varios recursos en un único archivo de Bicep o una plantilla de ARM, es importante el orden en que se crean los recursos. Este requisito es el resultado de las dependencias entre los recursos. Para estas dependencias, asegúrese de usar el elemento dependsOn para definir la dependencia en el recurso dependiente. Para obtener más información, consulte Definición del orden de implementación de recursos en plantillas de ARM o Dependencias de recursos en Bicep.

Requisitos previos

  • Los ejemplos están diseñados para ejecutarse en el contexto de un grupo de recursos existente.
  • Tanto Application Insights como los registros de almacenamiento requieren que tenga un Área de trabajo de Azure Log Analytics existente. Las áreas de trabajo se pueden compartir entre servicios y, como regla general, debe crear un área de trabajo en cada región geográfica para mejorar el rendimiento. Para obtener un ejemplo de cómo crear un área de trabajo de Log Analytics, vea Creación de un área de trabajo de Log Analytics. Puede encontrar el identificador de recurso del área de trabajo completo en una página de área de trabajo en el Azure Portal en configuración de configuración>Propiedades>Id. de recurso.
  • En este artículo se supone que ya ha creado un entorno administrado en Azure Container Apps. Necesita tanto el nombre como el identificador del entorno administrado para crear una aplicación de funciones hospedada en Container Apps.

Crear cuenta de almacenamiento

Todas las aplicaciones de funciones requieren una cuenta de almacenamiento de Azure. Se necesita una cuenta de uso general que admita blobs, tablas, colas y archivos. Para más información, vea Requisitos de la cuenta de almacenamiento de Azure Functions.

Importante

La cuenta de almacenamiento se usa para almacenar datos importantes de la aplicación, a veces incluido el propio código de la aplicación. Debe limitar el acceso desde otras aplicaciones y usuarios a la cuenta de almacenamiento.

En esta sección de ejemplo se crea una cuenta de almacenamiento de uso general Estándar v2:

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageAccountName
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
  properties: {
    supportsHttpsTrafficOnly: true
    defaultToOAuthAuthentication: true
    allowBlobPublicAccess: false
  }
}

Para obtener más contexto, consulte el archivo main.bicep completo en el repositorio de plantillas.

Para obtener más contexto, vea el archivo completo storage-account.bicep en el repositorio de ejemplo.

Debe establecer la cadena de conexión de esta cuenta de almacenamiento como la configuración de la aplicación AzureWebJobsStorage, que Functions requiere. Las plantillas de este artículo crean este valor de cadena de conexión en función de la cuenta de almacenamiento creada, que es un procedimiento recomendado. Para obtener más información, consulte Configuración de la aplicación.

Contenedor de implementación

Las implementaciones en una aplicación que se ejecuta en el plan de Consumo flexible requieren un contenedor en Azure Blob Storage como origen de implementación. Puede usar la cuenta de almacenamiento predeterminada o puede especificar una cuenta de almacenamiento independiente. Para obtener más información, vea Configuración de las opciones de implementación.

Esta cuenta de implementación ya debe configurarse al crear la aplicación, incluido el contenedor específico que se usa para las implementaciones. Para obtener más información sobre la configuración de implementaciones, vea Orígenes de implementación.

En este ejemplo se muestra cómo crear un contenedor en la cuenta de almacenamiento:

resource blobServices 'blobServices' = if (!empty(containers)) {
  name: 'default'
  properties: {
    deleteRetentionPolicy: deleteRetentionPolicy
  }
  resource container 'containers' = [for container in containers: {
    name: container.name
    properties: {
      publicAccess: contains(container, 'publicAccess') ? container.publicAccess : 'None'
    }
  }]
}

Para ver el fragmento de código en contexto, vea este ejemplo de implementación.

Otras opciones de implementación son configuradas con la propia aplicación.

Habilitación de los registros de almacenamiento

Dado que la cuenta de almacenamiento se usa para datos importantes de la aplicación de funciones, debe supervisar la modificación de ese contenido. Para supervisar la cuenta de almacenamiento, debe configurar los registros de recursos de Azure Monitor para Azure Storage. En esta sección ejemplo, se usa un área de trabajo de Log Analytics denominada myLogAnalytics como destino para estos registros.

resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2021-09-01' existing = {
  name:'default'
  parent:storageAccountName
}

resource storageDataPlaneLogs 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: '${storageAccountName}-logs'
  scope: blobService
  properties: {
    workspaceId: myLogAnalytics.id
    logs: [
      {
        category: 'StorageWrite'
        enabled: true
      }
    ]
    metrics: [
      {
        category: 'Transaction'
        enabled: true
      }
    ]
  }
}

Esta misma área de trabajo se puede usar para el recurso de Application Insights definido más adelante. Para obtener más información, incluido cómo trabajar con estos registros, consulte Supervisión de Azure Storage.

Creación de recursos de Application Insights

Debe usar Application Insights para supervisar las ejecuciones de la aplicación de funciones. Application Insights ahora requiere un área de trabajo de Azure Log Analytics, que se puede compartir. En estos ejemplos se supone que usa un área de trabajo existente y que tiene el identificador de recurso completo para el área de trabajo. Para más información, vea Área de trabajo de Azure Log Analytics.

En esta sección de ejemplo, el recurso de Application Insights se define con el tipo Microsoft.Insights/components y el tipo web:

resource applicationInsight 'Microsoft.Insights/components@2020-02-02' = {
  name: applicationInsightsName
  location: appInsightsLocation
  tags: tags
  kind: 'web'
  properties: {
    Application_Type: 'web'
    WorkspaceResourceId: '<FULLY_QUALIFIED_RESOURCE_ID>'
  }
}

Para obtener más contexto, consulte el archivo main.bicep completo en el repositorio de plantillas.

La conexión a la aplicación de funciones debe proporcionarse mediante la configuración de la aplicación APPLICATIONINSIGHTS_CONNECTION_STRING. Para obtener más información, consulte Configuración de la aplicación.

Los ejemplos de este artículo obtienen el valor de cadena de conexión de la instancia creada. En su lugar, es posible que las versiones anteriores usen APPINSIGHTS_INSTRUMENTATIONKEY para establecer la clave de instrumentación, que ya no se recomienda.

Creación de plan de hospedaje

Las aplicaciones hospedadas en un plan de Consumo flexible de Azure Functions, Plan Premium, o Plan dedicado (App Service ) deben tener definido explícitamente el plan de hospedaje.

Flex Consumption es un plan de hospedaje basado en Linux que se basa en el consumo paga por lo que se usa modelo de facturación sin servidor. Las características del plan admiten redes privadas, selección de tamaño de memoria de instancia y compatibilidad mejorada con identidades administradas.

Un plan de Consumo flexible es un tipo especial de serverfarm recurso. Puede especificarlo mediante FC1 para el valor de la propiedad Name en la propiedad sku con un valor tier de FlexConsumption.

En esta sección de ejemplo se crea el plan de Consumo flexible:

resource flexFuncPlan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: planName
  location: location
  tags: tags
  kind: 'functionapp'
  sku: {
    tier: 'FlexConsumption'
    name: 'FC1'
  }
  properties: {
    reserved: true
  }
}

Para obtener más contexto, vea el archivo completo function.bicep en el repositorio de ejemplo del plan de Consumo flexible.

Dado que el plan de Consumo flexible actualmente solo admite Linux, también debe establecer la propiedad reserved en true.

El plan Prémium ofrece la misma escala que el plan de consumo, pero incluye funcionalidades adicionales y recursos dedicados. Para obtener más información, consulte Plan Premium de Azure Functions.

Un plan Premium es un tipo especial de recurso serverfarm. Puede especificarlo mediante EP1, EP2 o EP3 para el valor de la propiedad Name en la propiedad sku. La manera en que defina el plan de hospedaje de Functions depende de si la aplicación de funciones se ejecuta en Windows o en Linux. En esta sección de ejemplo se crea un plan EP1:

resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: hostingPlanName
  location: location
  sku: {
    name: 'EP1'
    tier: 'ElasticPremium'
    family: 'EP'
  }
  kind: 'elastic'
  properties: {
    maximumElasticWorkerCount: 20
  }
}

Para obtener más contexto, consulte el archivo main.bicep completo en el repositorio de plantillas.

Para obtener más información sobre el objeto sku, consulte SkuDefinition o revise las plantillas de ejemplo.

En el plan dedicado (App Service), la aplicación de funciones se ejecuta en máquinas virtuales dedicadas en las SKU de los niveles Básico, Estándar y Premium en planes de App Service, de un modo similar a las aplicaciones web. Para obtener más información, consulte Plan dedicado.

Para ver un archivo de Bicep o una plantilla de Azure Resource Manager de ejemplo, consulte Aplicación de funciones en el plan de App Service.

En Functions, el plan Dedicado es simplemente un plan de App Service normal, que se define mediante un recurso serverfarm. Debe proporcionar al menos el valor name. Para obtener una lista de nombres de plan admitidos, consulte el valor --sku en az appservice plan create para obtener la lista actual de valores admitidos para un plan dedicado.

La forma en que defina el plan de hospedaje depende de si la aplicación de funciones se ejecuta en Windows o en Linux:

resource hostingPlanName 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: hostingPlanName
  location: location
  sku: {
    tier: 'Standard'
    name: 'S1'
    size: 'S1'
    family: 'S'
    capacity: 1
  }
}

Para obtener más contexto, consulte el archivo main.bicep completo en el repositorio de plantillas.

Creación de plan de hospedaje

No es necesario definir explícitamente un recurso de plan de hospedaje de consumo. Al omitir esta definición de recurso, se crea o selecciona automáticamente un plan por región al crear el propio recurso de la aplicación de funciones.

Puede definir explícitamente un plan de consumo como un tipo especial de recurso serverfarm, que se especifica mediante el valor Dynamic de las propiedades computeMode y sku. En esta sección de ejemplo se muestra cómo definir explícitamente un plan de consumo. La forma en que defina un plan de hospedaje depende de si la aplicación de funciones se ejecuta en Windows o en Linux.

resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: hostingPlanName
  location: location
  sku: {
    name: 'Y1'
    tier: 'Dynamic'
    size: 'Y1'
    family: 'Y'
    capacity: 0
  }
  properties: {
    computeMode: 'Dynamic'
  }
}

Para obtener más contexto, consulte el archivo main.bicep completo en el repositorio de plantillas.

Entorno de Kubernetes

Azure Functions se puede implementar en Kubernetes habilitado para Azure Arc como un proyecto de código o una aplicación de funciones contenedorizada.

Para crear la aplicación y planear los recursos, ya debe haber creado un entorno de Kubernetes de App Service para un clúster de Kubernetes habilitado para Azure Arc. En los ejemplos de este artículo se supone que tiene el identificador de recurso de la ubicación personalizada (customLocationId) y el entorno de Kubernetes de App Service (kubeEnvironmentId) en el que se va a implementar, que se establecen en este ejemplo:

param kubeEnvironmentId string
param customLocationId string

Tanto los sitios como los planes deben hacer referencia a la ubicación personalizada mediante un campo extendedLocation. Como se muestra en este ejemplo truncado, extendedLocation se encuentra fuera de properties, como un elemento del mismo nivel que kind y location:

resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  ...
  {
    extendedLocation: {
      name: customLocationId
    }
  }
}

El recurso del plan debe usar el valor de Kubernetes (K1) para SKU, el campo kind debe ser linux,kubernetes y la propiedad reserved debe ser true, ya que es una implementación de Linux. También debe establecer extendedLocation y kubeEnvironmentProfile.id en el identificador de ubicación personalizada y el identificador de entorno de Kubernetes, respectivamente, que podría tener un aspecto similar a esta sección de ejemplo:

resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: hostingPlanName
  location: location
  kind: 'linux,kubernetes'
  sku: {
    name: 'K1'
    tier: 'Kubernetes'
  }
  extendedLocation: {
    name: customLocationId
  }
  properties: {
    kubeEnvironmentProfile: {
      id: kubeEnvironmentId
    }
    reserved: true
  }
}

Crear la aplicación de función

El recurso de la aplicación de funciones se define mediante un recurso de tipo Microsoft.Web/sites y kind que incluye functionapp, como mínimo.

La forma en que se define un recurso de aplicación de funciones depende de si se hospeda en Linux o en Windows:

Para obtener una lista de la configuración de la aplicación necesaria al ejecutarse en Windows, consulte Configuración de la aplicación. Para ver un archivo de Bicep o una plantilla de Azure Resource Manager de ejemplo, consulte la plantilla Aplicación de funciones hospedada en Windows en un plan de consumo.

Para obtener una lista de la configuración de la aplicación necesaria al ejecutarse en Windows, consulte Configuración de la aplicación.

Flex Consumption reemplaza a muchas de las propiedades estándar de configuración de la aplicación y de sitio que se usan en las implementaciones de plantillas de Bicep y ARM. Para obtener más información, consulte Configuración de la aplicación.

resource flexFuncApp 'Microsoft.Web/sites@2023-12-01' = {
  name: appName
  location: location
  tags: tags
  kind: 'functionapp,linux'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: flexFuncPlan.id
    siteConfig: {
      appSettings: [
        {
          name: 'AzureWebJobsStorage__accountName'
          value: storage.name
        }
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: appInsights.properties.ConnectionString
        }
      ]
    }
    functionAppConfig: {
      deployment: {
        storage: {
          type: 'blobContainer'
          value: '${storage.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
          authentication: {
            type: 'SystemAssignedIdentity'
          }
        }
      }
      scaleAndConcurrency: {
        maximumInstanceCount: maximumInstanceCount
        instanceMemoryMB: instanceMemoryMB
      }
      runtime: { 
        name: functionAppRuntime
        version: functionAppRuntimeVersion
      }
    }
  }
}

Para obtener más contexto, vea el archivo completo function.bicep en el repositorio de ejemplo del plan de Consumo flexible.

Nota:

Se elige definir de manera opcional el plan de con, deberá establecer la propiedad serverFarmId en la aplicación de forma que apunte al identificador de recurso del plan. Asegúrese de que la aplicación de funciones dispone del valor dependsOn, que también hace referencia al plan. Si no ha definido explícitamente un plan, se crea uno automáticamente.

Establezca la propiedad serverFarmId en la aplicación para que apunte al identificador de recurso del plan. Asegúrese de que la aplicación de funciones dispone del valor dependsOn, que también hace referencia al plan.

resource functionAppName_resource 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    serverFarmId: hostingPlanName.id
    siteConfig: {
      appSettings: [
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: applicationInsightsName.properties.ConnectionString
        }
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'WEBSITE_CONTENTSHARE'
          value: toLower(functionAppName)
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          name: 'WEBSITE_NODE_DEFAULT_VERSION'
          value: '~14'
        }
      ]
    }
  }
}

Para obtener un ejemplo completo de un extremo a otro, consulte este archivo main.bicep.

resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    serverFarmId: hostingPlan.id
    siteConfig: {
      alwaysOn: true
      appSettings: [
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: applicationInsightsName.properties.ConnectionString
        }
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          name: 'WEBSITE_NODE_DEFAULT_VERSION'
          value: '~14'
        }
      ]
    }
  }
}

Para obtener un ejemplo completo de un extremo a otro, consulte este archivo main.bicep.

Orígenes de la implementación

Puede usar la configuración del sitio linuxFxVersion para solicitar que se implemente un contenedor de Linux específico en la aplicación cuando se cree. Se requieren más configuraciones para acceder a imágenes en un repositorio privado. Para obtener más información, consulte Configuración de la aplicación.

Importante

Al crear contenedores propios, tendrá que mantener actualizada la imagen base del contenedor con la imagen base compatible más reciente. Las imágenes base admitidas para Azure Functions son específicas del lenguaje y se encuentran en los repositorios de imágenes base de Azure Functions.

El equipo de Functions se compromete a publicar actualizaciones mensuales de estas imágenes base. Las actualizaciones regulares incluyen las actualizaciones de versión secundaria y las correcciones de seguridad más recientes tanto del entorno de ejecución de Functions como de los lenguajes. Debería actualizar periódicamente el contenedor desde la imagen base más reciente y volver a implementar desde la versión actualizada del contenedor.

El archivo de Bicep o la plantilla de ARM también pueden definir de manera opcional una implementación para el código de función, que podría incluir estos métodos:

El plan de consumo flexible mantiene el código del proyecto en el archivo de paquete comprimido zip en un contenedor de Blob Storage conocido como contenedor de implementación. Puede configurar tanto la cuenta de almacenamiento como el contenedor que se usa para la implementación. Para obtener más información, consulte Implementación.

Debe usar una implementación para publicar el paquete de código en el contenedor de implementación. Durante una implementación de ARM o Bicep, puede hacerlo definiendo un origen de paquete que use la extensión /onedeploy. Si decide cargar directamente el paquete en el contenedor, el paquete no se implementará automáticamente.

Contenedor de implementación

La cuenta de almacenamiento y el contenedor específicos que se usan para las implementaciones, el método de autenticación y las credenciales se establecen en el elemento functionAppConfig.deployment.storage del properties para el sitio. El contenedor y cualquier configuración de la aplicación deben existir cuando se crea la aplicación. Para obtener un ejemplo de cómo crear el contenedor de almacenamiento, vea Contenedor de implementación.

En este ejemplo se usa una identidad administrada asignada por el sistema para acceder al contenedor de Blob Storage especificado, que se crea en otra parte de la implementación:

deployment: {
  storage: {
    type: 'blobContainer'
    value: '${storage.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
    authentication: {
      type: 'SystemAssignedIdentity'
    }
  }
}

Al usar identidades administradas, también debe habilitar la aplicación de funciones para acceder a la cuenta de almacenamiento mediante la identidad, como se muestra en este ejemplo:

// Allow access from function app to storage account using a managed identity
resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  name: guid(storage.id, storageRoleDefinitionId)
  scope: storage
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageRoleDefinitionId)
    principalId: flexFuncApp.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

Para obtener un ejemplo de referencia completo, vea este archivo de Bicep.

En este ejemplo es necesario conocer el valor GUID del rol que se va a asignar. Puede obtener este valor de identificador para cualquier nombre de rol descriptivo mediante el comando az role definition list, como en este ejemplo:

az role definition list --output tsv --query "[?roleName=='Storage Blob Data Owner'].{name:name}"

Al usar una cadena de conexión en lugar de identidades administradas, debe establecer el authentication.type en StorageAccountConnectionString y establecer authentication.storageAccountConnectionStringName en el nombre de la configuración de la aplicación que contiene la cadena de conexión de la cuenta de almacenamiento de implementación.

Paquete de implementación

El plan de consumo flexible usa una implementación para implementar el proyecto de código. El propio paquete de código es el mismo que usaría para la implementación zip en otros planes de hospedaje de Functions. Sin embargo, el nombre del propio archivo de paquete debe ser released-package.zip.

Para incluir un paquete de implementación único en la plantilla, use la definición de recurso /onedeploy para la dirección URL remota que contiene el paquete de implementación. El host de Functions debe poder acceder tanto a este origen de paquete remoto como al contenedor de implementación.

En este ejemplo se agrega un origen de implementación único a una aplicación existente:

@description('The name of the function app.')
param functionAppName string

@description('The location into which the resources should be deployed.')
param location string = resourceGroup().location

@description('The zip content URL for released-package.zip.')
param packageUri string

resource functionAppName_OneDeploy 'Microsoft.Web/sites/extensions@2022-09-01' = {
  name: '${functionAppName}/onedeploy'
  location: location
  properties: {
    packageUri: packageUri
    remoteBuild: false 
  }
}

El archivo de Bicep o la plantilla de ARM también pueden definir de manera opcional una implementación para el código de función mediante un paquete de implementación zip.

Para implementar la aplicación de forma correcta mediante Azure Resource Manager, es importante comprender cómo se implementan los recursos en Azure. En la mayoría de los ejemplos, las configuraciones de nivel superior se aplican mediante siteConfig. Es importante establecer estas configuraciones en un nivel superior porque transmiten información al motor de implementación y en tiempo de ejecución de Functions. Se requiere información de nivel superior antes de aplicar el recurso secundario sourcecontrols/web. Aunque es posible configurar estas opciones en el recurso de nivel secundario config/appSettings, en algunos casos la aplicación de funciones debe implementarse antesconfig/appSettings de aplicarse.

Paquete de implementación zip

La implementación zip es una manera recomendada de implementar el código de la aplicación de funciones. De manera predeterminada, las funciones que usan la implementación zip se ejecutan en el propio paquete de implementación. Para obtener más información, incluidos los requisitos de un paquete de implementación, consulte Implementación zip para Azure Functions. Al usar la automatización de la implementación de recursos, puede hacer referencia al paquete de implementación .zip en la plantilla de ARM o Bicep.

Para usar la implementación zip en la plantilla, establezca el valor WEBSITE_RUN_FROM_PACKAGE de la aplicación en 1 e incluya la definición de recursos /zipDeploy.

En el caso de un plan de consumo en Linux, establezca el URI del paquete de implementación directamente en el valor WEBSITE_RUN_FROM_PACKAGE, como se muestra en esta plantilla de ejemplo.

En este ejemplo se agrega un origen de implementación zip a una aplicación existente:

@description('The name of the function app.')
param functionAppName string

@description('The location into which the resources should be deployed.')
param location string = resourceGroup().location

@description('The zip content url.')
param packageUri string

resource functionAppName_ZipDeploy 'Microsoft.Web/sites/extensions@2021-02-01' = {
  name: '${functionAppName}/ZipDeploy'
  location: location
  properties: {
    packageUri: packageUri
  }
}

Tenga en cuenta lo siguiente al incluir recursos de implementación zip en la plantilla:

  • packageUri debe ser una ubicación a la que puede acceder Functions. Considere la posibilidad de usar Azure Blob Storage con una firma de acceso compartido (SAS). Una vez expirada la SAS, Functions ya no puede acceder al recurso compartido para las implementaciones. Cuando vuelva a generar la SAS, recuerde actualizar el valor WEBSITE_RUN_FROM_PACKAGE con el nuevo valor de URI.

  • Al establecer WEBSITE_RUN_FROM_PACKAGE en un URI, deberá sincronizar manualmente los desencadenadores.

  • Asegúrese de establecer siempre toda la configuración de la aplicación necesaria en la colección appSettings al agregar o actualizar la configuración. La actualización quita la configuración existente no establecida explícitamente. Para obtener más información, consulte Configuración de la aplicación.

  • Functions no admite Web Deploy (msdeploy) para implementaciones de paquetes. En su lugar, debe usar la implementación zip en las canalizaciones de implementación y la automatización. Para más información, consulte Implementación de archivos ZIP en Azure Functions.

Compilaciones remotas

El proceso de implementación supone que el archivo .zip que usa o una implementación zip contiene una aplicación lista para ejecutarse. Esto significa que, de manera predeterminada, no se ejecutan personalizaciones.

Hay escenarios que requieren que recompile la aplicación de forma remota. Un ejemplo de este tipo es cuando necesita incluir paquetes específicos de Linux en Python o Node.js aplicaciones desarrolladas en un equipo Windows. En este caso, puede configurar Functions para realizar una compilación remota en el código después de la implementación del archivo zip.

La forma en que solicita una compilación remota depende del sistema operativo en el que se va a implementar:

Cuando se implementa una aplicación en Windows, se ejecutan comandos específicos del lenguaje (como dotnet restore para aplicaciones de C# o npm install para aplicaciones de Node.js).

Para habilitar los mismos procesos de compilación que obtiene con la integración continua, agregue SCM_DO_BUILD_DURING_DEPLOYMENT=true a la configuración de la aplicación en el código de implementación y quite WEBSITE_RUN_FROM_PACKAGE completamente.

Contenedores de Linux

Si va a implementar una aplicación de funciones contenedorizada en un plan Premium o Dedicado de Azure Functions, debe hacer lo siguiente:

Si falta alguna configuración, es posible que se produzca un error en el aprovisionamiento de aplicaciones con este error HTTP/500:

Function app provisioning failed.

Para obtener más información, consulte Configuración de la aplicación.

resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    serverFarmId: hostingPlan.id
    siteConfig: {
      appSettings: [
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          name: 'WEBSITE_NODE_DEFAULT_VERSION'
          value: '~14'
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'DOCKER_REGISTRY_SERVER_URL'
          value: dockerRegistryUrl
        }
        {
          name: 'DOCKER_REGISTRY_SERVER_USERNAME'
          value: dockerRegistryUsername
        }
        {
          name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
          value: dockerRegistryPassword
        }
        {
          name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE'
          value: 'false'
        }
      ]
      linuxFxVersion: 'DOCKER|myacr.azurecr.io/myimage:mytag'
    }
  }
  dependsOn: [
    storageAccount
  ]
}

Al implementar funciones contenedorizadas en Azure Container Apps, la plantilla debe:

  • Establezca el campo kind en un valor de functionapp,linux,container,azurecontainerapps.
  • Establezca la propiedad de sitio managedEnvironmentId en el URI completo del entorno de Container Apps.
  • Agregue un vínculo de recurso en la colección dependsOn del sitio al crear un recurso Microsoft.App/managedEnvironments al mismo tiempo que el sitio.

La definición de una aplicación de funciones contenedorizada implementada desde un registro de contenedor privado en un entorno de Container Apps existente podría tener un aspecto similar al de este ejemplo:

resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  kind: 'functionapp,linux,container,azurecontainerapps'
  location: location
  properties: {
    serverFarmId: hostingPlanName
    siteConfig: {
      linuxFxVersion: 'DOCKER|myacr.azurecr.io/myimage:mytag'
      appSettings: [
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: applicationInsightsName.properties.ConnectionString
        }
      ]
    }
    managedEnvironmentId: managedEnvironmentId
  }
  dependsOn: [
    storageAccount
    hostingPlan
  ]
}

Al implementar funciones en Azure Arc, el valor establecido para el campo kind del recurso de la aplicación de funciones depende del tipo de implementación:

Tipo de implementación Valor de campo kind
Implementación solo de código functionapp,linux,kubernetes
Implementación de contenedores functionapp,linux,kubernetes,container

También debe establecer customLocationId como hizo para el recurso del plan de hospedaje.

La definición de una aplicación de funciones contenedorizada, con una imagen de inicio rápido de .NET 6, podría tener este aspecto:

resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
  name: functionAppName
  kind: 'kubernetes,functionapp,linux,container'
  location: location
  extendedLocation: {
    name: customLocationId
  }
  properties: {
    serverFarmId: hostingPlanName
    siteConfig: {
      linuxFxVersion: 'DOCKER|mcr.microsoft.com/azure-functions/4-dotnet-isolated6.0-appservice-quickstart'
      appSettings: [
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${storageAccount.listKeys().keys[0].value}'
        }
        {
          name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
          value: applicationInsightsName.properties.ConnectionString
        }
      ]
      alwaysOn: true
    }
  }
  dependsOn: [
    storageAccount
    hostingPlan
  ]
}

Configuración de aplicaciones

En un plan de Consumo flexible, configurará la aplicación de funciones en Azure con dos tipos de propiedades:

Configuración Propiedad Microsoft.Web/sites
Configuración de aplicaciones functionAppConfig
Configuración de la aplicación Colección siteConfig.appSettings

Estas configuraciones de aplicación se mantienen en functionAppConfig:

Comportamiento Configuración en functionAppConfig
Instancias siempre preparadas scaleAndConcurrency.alwaysReady
Origen de implementación deployment
Tamaño de memoria de instancia scaleAndConcurrency.instanceMemoryMB
Simultaneidad del desencadenador HTTP scaleAndConcurrency.triggers.http.perInstanceConcurrency
Language Runtime runtime.name
Versión de lenguaje runtime.version
Número máximo de instancias scaleAndConcurrency.maximumInstanceCount

El plan de Consumo flexible también admite estas opciones de configuración de la aplicación:

Functions proporciona las siguientes opciones para configurar la aplicación de funciones en Azure:

Configuración PropiedadMicrosoft.Web/sites
Configuración del sitio siteConfig
Configuración de aplicación Colección siteConfig.appSettings

Esta configuración del sitio es necesaria en la propiedad siteConfig:

Esta configuración del sitio solo es necesaria cuando se usan identidades administradas para obtener la imagen de una instancia de Azure Container Registry:

Esta configuración de la aplicación es necesaria (o recomendada) para un sistema operativo específico y una opción de hospedaje:

Esta configuración de la aplicación es necesaria para las implementaciones de contenedores:

Esta configuración solo es necesaria al implementar desde un registro de contenedor privado:

Tenga en cuenta estas consideraciones al trabajar con la configuración del sitio y la aplicación mediante archivos de Bicep o plantillas de ARM:

  • La configuración opcional de alwaysReady contiene una matriz de uno o varios objetos {name,instanceCount}, con uno para cada grupo de escalado por función. Estos son los grupos de escalado que se usan para tomar decisiones sobre el escalado siempre listo. En este ejemplo se establecen recuentos siempre listos para el grupo de http y una sola función denominada helloworld, que es de tipo desencadenador no agrupado:
      alwaysReady: [
        {
          name: 'http'
          instanceCount: 2
        }
        {
          name: 'function:helloworld'
          instanceCount: 1
        }
      ]
    
  • Hay consideraciones importantes para cuando se debe establecer WEBSITE_CONTENTSHARE en una implementación automatizada. Para obtener instrucciones detalladas, consulta la referencia WEBSITE_CONTENTSHARE.
  • En el caso de las implementaciones de contenedores, también se establece WEBSITES_ENABLE_APP_SERVICE_STORAGE en false, ya que el contenido de la aplicación se proporciona en el propio contenedor.
  • Siempre debe definir la configuración de la aplicación como una colección siteConfig/appSettings del recurso Microsoft.Web/sites que se va a crear, como se hace en los ejemplos de este artículo. Esta definición garantiza que la configuración que la aplicación de funciones necesita ejecutar está disponible en el inicio inicial.

  • Al agregar o actualizar la configuración de la aplicación mediante plantillas, asegúrese de incluir toda la configuración existente con la actualización. Debe hacerlo porque las llamadas API de REST de actualización subyacente reemplazan todo el recurso /config/appsettings. Si quita la configuración existente, la aplicación de funciones no se ejecutará. Para actualizar mediante programación la configuración de la aplicación individual, puede usar la CLI de Azure, Azure PowerShell o Azure Portal para realizar estos cambios. Para más información, consulte Trabajar con la configuración de la aplicación.

Implementaciones de ranuras

Functions le permite implementar diferentes versiones del código en puntos de conexión únicos en la aplicación de funciones. Esta opción facilita el desarrollo, validación e implementación de actualizaciones de funciones sin afectar a las funciones que se ejecutan en producción. Las ranuras de implementación son una característica de Azure App Service. El número de ranuras disponibles depende del plan de hospedaje. Para obtener más información, consulte Funciones de ranuras de implementación de Azure Functions.

Un recurso de ranura se define de la misma manera que un recurso de aplicación de funciones (Microsoft.Web/sites), pero en su lugar se usa el identificador de recursos Microsoft.Web/sites/slots. Para obtener un ejemplo de implementación (en Bicep y plantillas de ARM) que crea una ranura de producción y un espacio de ensayo en un plan Premium, consulte Aplicación de funciones de Azure con una ranura de implementación.

Para obtener información sobre cómo intercambiar ranuras mediante plantillas, vea Automatización con plantillas de Resource Manager.

Tenga en cuenta las siguientes consideraciones al trabajar con implementaciones de ranuras:

  • No establezca explícitamente el valor WEBSITE_CONTENTSHARE en la definición de la ranura de implementación. Esta configuración se genera automáticamente cuando se crea la aplicación en la ranura de implementación.

  • Al intercambiar ranuras, algunas opciones de configuración de la aplicación se consideran "persistentes", ya que permanecen con la ranura y no con el código que se va a intercambiar. Puede definir esta configuración de ranura incluyendo "slotSetting":true en la definición del valor de configuración de la aplicación específica de la plantilla. Para obtener más información, consulte Administración de la configuración.

Implementaciones protegidas

Puede crear la aplicación de funciones en una implementación en la que se haya protegido uno o varios de los recursos mediante la integración con redes virtuales. La integración con una red virtual para la aplicación de funciones se define mediante un recurso Microsoft.Web/sites/networkConfig. Esta integración depende de la aplicación de funciones a la que se hace referencia y de los recursos de red virtual. La aplicación de funciones también puede depender de otros recursos de red privados, como puntos de conexión privados y rutas. Para obtener más información, vea las opciones de red de Azure Functions.

Estos proyectos proporcionan ejemplos basados en Bicep de cómo implementar las aplicaciones de funciones en una red virtual, incluidas las restricciones de acceso de red:

Al crear una implementación que usa una cuenta de almacenamiento protegida, debes establecer explícitamente la configuración WEBSITE_CONTENTSHARE y crear el recurso compartido de archivos denominado en esta configuración. Asegúrate de crear un recurso Microsoft.Storage/storageAccounts/fileServices/shares con el valor de WEBSITE_CONTENTSHARE, como se muestra en este ejemplo (plantilla de ARM|archivo Bicep). También deberá establecer la propiedad del sitio vnetContentShareEnabled en true.

Nota:

Cuando esta configuración no forme parte de una implantación que utiliza una cuenta de almacenamiento protegida, aparece este error al validar la implementación: Could not access storage account using provided connection string.

Estos proyectos proporcionan ejemplos de plantillas de ARM y Bicep sobre cómo implementar las aplicaciones de funciones en una red virtual, incluidas las restricciones de acceso de red:

Escenario restringido Descripción
Creación de una aplicación de funciones con integración de red virtual La aplicación de funciones se crea en una red virtual con acceso total a los recursos de esa red. El acceso entrante y saliente a la aplicación de funciones no está restringido. Para obtener más información, consulte Integración de la red virtual.
Creación de una aplicación de funciones que tenga acceso a una cuenta de almacenamiento protegida La aplicación de funciones creada usa una cuenta de almacenamiento protegida, a la que Functions accede mediante puntos de conexión privados. Para obtener más información, consulte Restricción de la cuenta de almacenamiento a una red virtual.
Creación de una aplicación de funciones y una cuenta de almacenamiento que usan puntos de conexión privados Solo se puede acceder a la aplicación de funciones creada mediante puntos de conexión privados y se usan puntos de conexión privados para acceder a los recursos de almacenamiento. Para obtener más información, consulte Puntos de conexión privados.

Configuración de red restringida

También es posible que tenga que usar esta configuración cuando la aplicación de funciones tenga restricciones de red:

Configuración valor Descripción
WEBSITE_CONTENTOVERVNET 1 Configuración de la aplicación que permite que la aplicación de funciones se escale cuando la cuenta de almacenamiento esté restringida a una red virtual. Para obtener más información, consulte Restricción de la cuenta de almacenamiento a una red virtual.
vnetrouteallenabled 1 Valor del sitio que obliga a todo el tráfico de la aplicación de funciones a usar la red virtual. Para obtener más información, consulte Integración de la red virtual regional. Este valor de sitio reemplaza la configuración de la aplicación WEBSITE_VNET_ROUTE_ALL.

Consideraciones para las restricciones de red

Al restringir el acceso a la cuenta de almacenamiento a través de los puntos de conexión privados, no podrá acceder a la cuenta de almacenamiento a través del portal ni de ningún dispositivo fuera de la red virtual. Puede conceder acceso a la dirección IP protegida o a la red virtual en la cuenta de almacenamiento mediante Administración de la regla de acceso de red predeterminada.

Claves de acceso de función

Las claves de acceso de función de nivel de host se definen como recursos de Azure. Esto significa que puede crear y administrar claves de host en las plantillas de ARM y los archivos de Bicep. Una clave de host se define como un recurso de tipo Microsoft.Web/sites/host/functionKeys. En este ejemplo se crea una clave de acceso de nivel de host denominada my_custom_key cuando se crea la aplicación de funciones:

resource functionKey 'Microsoft.Web/sites/host/functionKeys@2022-09-01' = {
  name: '${parameters('name')}/default/my_custom_key'
  properties: {
    name: 'my_custom_key'
  }
  dependsOn: [
    resourceId('Microsoft.Web/Sites', parameters('name'))
  ]
}

En este ejemplo, el parámetro name es el nombre de la nueva aplicación de funciones. Debe incluir una configuración de dependsOn para garantizar que la clave se crea con la nueva aplicación de funciones. Por último, el objeto properties de la clave host también puede incluir una propiedad value que se puede usar para establecer una clave específica.

Cuando no establece la propiedad value, Functions genera automáticamente una nueva clave cuando se crea el recurso, que se recomienda. Para más información sobre las claves de acceso, incluidos los procedimientos recomendados de seguridad para trabajar con claves de acceso, vea Trabajar con claves de acceso en Azure Functions.

Creación de la plantilla

Los expertos con plantillas de ARM o Bicep pueden codificar manualmente sus implementaciones mediante un editor de texto sencillo. Para el resto de nosotros, hay varias maneras de facilitar el proceso de desarrollo:

  • Visual Studio Code: hay extensiones disponibles para ayudarle a trabajar con archivos de Bicep y plantillasde ARM. Puede usar estas herramientas para asegurarse de que el código es correcto y proporcionan alguna validación básica.

  • Azure Portal: al crear la aplicación de funciones y los recursos relacionados en el portal, la pantalla de Revisión y creación final tiene un vínculo Descargar una plantilla para la automatización.

    Descargue el vínculo de plantilla del proceso de creación de Azure Functions en Azure Portal.

    Este vínculo muestra la plantilla de ARM generada en función de las opciones que eligió en el portal. Esta plantilla puede parecer un poco compleja al crear una aplicación de funciones con muchos recursos nuevos. Sin embargo, puede proporcionar una buena referencia para el aspecto de la plantilla de ARM.

Validación de la plantilla

Al crear manualmente el archivo de plantilla de implementación, es importante validar la plantilla antes de la implementación. Todos los métodos de implementación validan la sintaxis de la plantilla y generan un mensaje de error validation failed como se muestra en el siguiente ejemplo con formato JSON:

{"error":{"code":"InvalidTemplate","message":"Deployment template validation failed: 'The resource 'Microsoft.Web/sites/func-xyz' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.","additionalInfo":[{"type":"TemplateViolation","info":{"lineNumber":0,"linePosition":0,"path":""}}]}}

Los métodos siguientes se pueden usar para validar la plantilla antes de la implementación:

La siguiente tarea de implementación del grupo de recursos de Azure v2 con deploymentMode: 'Validation' indica a Azure Pipelines que valide la plantilla.

- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    subscriptionId: # Required subscription ID
    action: 'Create Or Update Resource Group'
    resourceGroupName: # Required resource group name
    location: # Required when action == Create Or Update Resource Group
    templateLocation: 'Linked artifact'
    csmFile: # Required when  TemplateLocation == Linked Artifact
    csmParametersFile: # Optional
    deploymentMode: 'Validation'

También puede crear un grupo de recursos de prueba para buscar errores de comprobación e implementación.

Implementación de la plantilla

Puede usar cualquiera de los siguientes métodos para implementar el archivo de Bicep y la plantilla:

Botón Implementación en Azure

Nota

Este método no admite actualmente la implementación de archivos de Bicep.

Reemplace <url-encoded-path-to-azuredeploy-json> por una versión codificada de la URL de la ruta de acceso sin formato del archivo azuredeploy.json en GitHub.

Este es un ejemplo donde se usa Markdown:

[![Deploy to Azure](https://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>)

Este es un ejemplo donde se usa HTML:

<a href="https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>" target="_blank"><img src="https://azuredeploy.net/deploybutton.png"></a>

Implementación mediante PowerShell

Los siguientes comandos de PowerShell crean un grupo de recursos e implementan un archivo de Bicep o una plantilla de ARM que crea una aplicación de funciones con sus recursos necesarios. Para la ejecución local, es preciso tener instalado Azure PowerShell. Para iniciar sesión en Azure, primero debe ejecutar Connect-AzAccount.

# Register Resource Providers if they're not already registered
Register-AzResourceProvider -ProviderNamespace "microsoft.web"
Register-AzResourceProvider -ProviderNamespace "microsoft.storage"

# Create a resource group for the function app
New-AzResourceGroup -Name "MyResourceGroup" -Location 'West Europe'

# Deploy the template
New-AzResourceGroupDeployment -ResourceGroupName "MyResourceGroup" -TemplateFile main.bicep  -Verbose

Para probar esta implementación, puede usar una plantilla como esta, que crea una aplicación de funciones en Windows en un plan de consumo.

Pasos siguientes

Aprenda a desarrollar y configurar Azure Functions.