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.
Cuando una implementación presenta un error, necesita una manera de recuperarse rápidamente. En este artículo se explica cómo recuperarse de una implementación fallida en una aplicación de funciones Flex Consumption mediante un proceso de integración continua e implementación continua (CI/CD). Este proceso incluye estos métodos de recuperación:
| Método de recuperación | Velocidad | Cuándo se deben usar | Descripción |
|---|---|---|---|
| Volver a ejecutar la ejecución anterior completada correctamente (revertir) | El más rápido | Existe una versión correcta conocida, o bien no existe ningún cambio de datos o estado entre versiones. | Seleccione una ejecución anterior y vuelva a ejecutarla y espere a compilar e implementarla. |
git revert y luego git push (avance) |
Moderado | La solución es sencilla; de lo contrario, no se puede revertir el estado externo. | Identifica la confirmación que ha provocado el error, revierte los cambios y realiza el push. A continuación, espere el mismo tiempo de compilación e implementación. |
git commit una corrección urgente y luego git push (avanzar) |
Más lento | Se conoce la causa raíz y requiere una corrección específica. | Identificar la causa principal; crear, revisar, probar y combinar una corrección; y, a continuación, espere a que se complete la compilación e implementación. |
Estas estrategias recuperan tanto el código de la aplicación de funciones como la configuración de la aplicación, por lo que los cambios de configuración se pueden recuperar con cambios de código.
Por qué necesita CI/CD para recuperar un despliegue
Al implementar código en la aplicación de plan de consumo flexible:
- El código se implementa como un paquete zip en un contenedor de Blob Storage, que se monta en el inicio.
- Cada implementación sobrescribe el paquete actual.
- La plataforma no mantiene ningún historial de revisiones integrado para conservar las versiones anteriores.
- Actualmente no se admite la característica de ranuras de implementación .
- Los ajustes de la aplicación se aplican por separado a través del Portal de Azure, la CLI o la infraestructura como código (IaC), y la plataforma no puede restaurarlos a un estado anterior.
Estos comportamientos de implementación limitan sus opciones para recuperar la aplicación del plan Flex Consumption tras una implementación fallida.
El historial de Git y el proceso de CI/CD proporcionan la única manera de realizar un seguimiento de las implementaciones de código en un momento dado. Crear un despliegue que incluya tanto código como configuración permite recuperarse de una versión defectuosa haciendo que la siguiente ejecución apunte a un commit correcto conocido.
Para obtener más información sobre el modelo de implementación de Flex Consumption, consulte Plan Flex Consumption y Actualizaciones del sitio en el plan Flex Consumption.
Prerequisites
Una aplicación de funciones existente implementada en un plan de consumo flexible en Azure.
Código fuente en un repositorio de Git. Utilice etiquetas de Git o registre los SHA de las confirmaciones para cada lanzamiento para que pueda identificar rápidamente a qué versión volver.
Una implementación configurada para su aplicación de función:
Flujo de trabajo configurado con autenticación OIDC como se describe en Entrega continua mediante Acciones de GitHub. El flujo de trabajo debe usar
azure/login. La autenticación de perfil de publicación no admite losaz clicomandos usados en esta guía.
Preparación de la implementación para administrar la configuración de la aplicación
Antes de poder realizar una reversión completa, debes incluir la configuración de tu aplicación en el control de código fuente y aplicarla como parte de tu implementación. Aunque este enfoque le permite recuperar el código y la configuración en una sola nueva ejecución, requiere pasos adicionales, como aplicar la configuración, esperar reinicios y limpiar valores no declarados.
Tip
Cuando la implementación no incluye la configuración, solo puede revertir el código implementado, pero no la configuración.
En esta sección se detallan dos enfoques para administrar la configuración de la aplicación como parte de la implementación:
| Approach | En el flujo de trabajo (CLI de Azure) | En la definición del servicio (Bicep) |
|---|---|---|
| Cómo funciona | Los pasos de implementación aplican la configuración de un archivo JSON mediante az functionapp config appsettingsy, a continuación, quitan la configuración no declarada. |
La plantilla de Bicep define la configuración en siteConfig.appSettings; ARM reemplaza toda la colección al implementar |
| Complejidad | Moderado. Archivo JSON y pasos adicionales en la CLI en tu flujo de trabajo | Superior. Se requieren conocimientos de Bicep |
| Detección de desfase | No | Sí (what-if) |
| Mejor para | Introducción, equipos pequeños | Infraestructura compleja, multientorno y lista para producción |
Para obtener más información general sobre la configuración de la aplicación, consulta Referencia de configuración de aplicaciones para Azure Functions.
Consideraciones sobre la configuración de la aplicación
Preste atención a estas consideraciones al trabajar con la configuración mediante programación de los ajustes de la aplicación.
Important
Si no se incluye toda la configuración necesaria mediante cualquiera de los enfoques, se puede interrumpir la aplicación implementada.
Ambos enfoques de esta sección tratan el archivo de configuración como estado deseado completo. Quitan cualquier configuración de aplicación no declarada en el archivo de la aplicación en cada implementación. Incluya siempre toda la configuración necesaria para evitar interrumpir la aplicación.
Trata los cambios en
app-settings.jsony en las plantillas de archivos de Bicep con el mismo rigor que los cambios en el código. Revisa los cambios en la configuración de las solicitudes de incorporación de cambios (pull requests) para detectar errores de configuración antes de que lleguen a producción.Para obtener una seguridad óptima, siga estas instrucciones para las conexiones:
Use conexiones de identidad administrada siempre que sea posible. Configura conexiones basadas en identidad para el almacenamiento del host (
AzureWebJobsStorage), el almacenamiento de implementación y las conexiones de activadores y enlaces. Para obtener más información, consulte Configuración de las opciones de implementación.- Use referencias de Key Vault cuando sea inevitable usar secretos. Key Vault almacena de forma segura los secretos. En lugar de almacenar secretos directamente, puede usar una referencia para acceder de forma segura al secreto necesario en tiempo de ejecución. Para obtener más información, consulte Uso de referencias de Key Vault.
Al usar CI/CD, cada cambio en la configuración de la aplicación o el código desencadena una actualización de sitio independiente. De forma predeterminada, este proceso de implementación genera al menos dos actualizaciones de sitio: primero cuando se aplica la configuración y, a continuación, cuando se implementa código. Para los despliegues sin tiempo de inactividad, utilice en su lugar una estrategia de actualización progresiva, en la que las instancias se retiran del servicio y se reemplazan por lotes. Para obtener más información, consulte Actualizaciones de sitios en el plan Flex Consumption.
Configuración de las opciones de la aplicación en el flujo de trabajo
Sigue estos pasos básicos para añadir un archivo de configuración de los ajustes de la aplicación al despliegue del proyecto:
Cree un archivo JSON en el repositorio, como en
infra/app-settings.json. Este archivo debe incluir toda la configuración de la aplicación necesaria en un formato JSON similar al ejemplo siguiente:[ { "name": "FUNCTIONS_EXTENSION_VERSION", "value": "~4" }, { "name": "FUNCTIONS_WORKER_RUNTIME", "value": "dotnet-isolated" }, { "name": "APPLICATIONINSIGHTS_CONNECTION_STRING", "value": "InstrumentationKey=00000000-..." }, { "name": "AzureWebJobsStorage__blobServiceUri", "value": "https://mystorageaccount.blob.core.windows.net" }, { "name": "AzureWebJobsStorage__queueServiceUri", "value": "https://mystorageaccount.queue.core.windows.net" }, { "name": "AzureWebJobsStorage__tableServiceUri", "value": "https://mystorageaccount.table.core.windows.net" }, { "name": "MyFeatureFlag", "value": "true" }, { "name": "ServiceBus__fullyQualifiedNamespace", "value": "my-namespace.servicebus.windows.net" } ]En la definición de implementación específica, agregue pasos que apliquen la configuración antes de que se produzca la implementación de código, con una pausa de 30 segundos entre ellos.
En las secciones siguientes se proporcionan ejemplos de implementación específicos mediante ambos enfoques.
Ejemplo: implementación de app-settings.json
En este ejemplo de implementación se muestra cómo configurar la implementación para incluir la configuración. Elija la pestaña que coincida con el método de CI/CD.
Añada los siguientes pasos al trabajo deploy en su flujo de trabajo. Agregue actions/checkout@v4 al trabajo deploy para que infra/app-settings.json esté disponible, y agregue RESOURCE_GROUP al bloque env de nivel de flujo de trabajo. Los pasos primero aplican la configuración, esperan el reinicio, despliegan el código y luego eliminan la configuración no declarada.
deploy:
needs: build
steps:
- name: 'Checkout repository'
uses: actions/checkout@v4
- name: 'Download artifact from build job'
uses: actions/download-artifact@v4
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ./downloaded-artifact
- name: 'Log in to Azure'
uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Apply app settings'
run: |
az functionapp config appsettings set \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--settings @infra/app-settings.json
- name: 'Wait for settings restart'
run: sleep 30
- name: 'Deploy code'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ./downloaded-artifact
- name: 'Remove undeclared app settings'
run: |
DESIRED=$(jq -r '.[].name' infra/app-settings.json)
CURRENT=$(az functionapp config appsettings list \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--query "[].name" -o tsv)
TO_DELETE=""
for setting in $CURRENT; do
if ! echo "$DESIRED" | grep -qx "$setting"; then
TO_DELETE="$TO_DELETE $setting"
fi
done
if [ -n "$TO_DELETE" ]; then
az functionapp config appsettings delete \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--setting-names $TO_DELETE
fi
El azure/login@v2 paso del flujo de trabajo basado en OIDC proporciona la autenticación necesaria para los az cli comandos.
Definir la configuración en una implementación de Bicep
En el caso de las implementaciones de IaC, administre la configuración de la aplicación directamente en la plantilla de Bicep. Bicep sustituye de forma nativa toda la siteConfig.appSettingscolección en cada implementación sin necesidad de un paso de limpieza independiente. También admite la detección de desfase mediante what-if.
Al actualizar solo la sección de configuración de la aplicación del archivo de Bicep, todos los demás recursos de Azure permanecen sin modificar durante la implementación. Este artículo no aborda la creación de Bicep de principio a fin. Para obtener plantillas completas de consumo flexible, consulta Infraestructura como código de Azure Functions.
Aquí tienes el fragmento relevante de la plantilla de Bicep (solo la parte appSettings):
siteConfig: {
appSettings: [
{
name: 'MyFeatureFlag'
value: 'true'
}
{
name: 'ServiceBus__Connection'
value: '@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/sb-conn)'
}
]
}
Agregue pasos para implementar la plantilla de Bicep antes de la implementación de código, con una espera de 30 segundos entre ellas. La actualización de la configuración de la aplicación a través de Bicep es asincrónica. La aplicación se reinicia para recoger los nuevos valores e implementar código durante el reinicio puede producir un error.
- name: 'Deploy infrastructure'
run: |
az deployment group create \
--resource-group ${{ env.RESOURCE_GROUP }} \
--template-file infra/main.bicep \
--parameters appName=${{ env.AZURE_FUNCTIONAPP_NAME }}
- name: 'Wait for settings restart'
run: sleep 30
- name: 'Deploy code'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ./downloaded-artifact
Reversión de una implementación
La reversión consiste en volver a ejecutar una ejecución anterior que haya tenido éxito. Una reejecución recupera el SHA del commit original que desencadenó esa ejecución (no el HEAD actual de la rama), por lo que recompila y despliega el código y el archivo de configuración tal como estaban en ese momento. No se necesitan nuevas confirmaciones.
Para revertir un despliegue volviendo a ejecutar una ejecución anterior que se haya completado correctamente:
- Vaya a la pestaña Acciones del repositorio de GitHub.
- Busque la última ejecución correcta del flujo de trabajo antes de la implementación incorrecta.
- Seleccione Volver a ejecutar todos los trabajos.
- El flujo de trabajo extrae la confirmación de esa ejecución, recompila, implementa el código y sincroniza la configuración de la aplicación a partir de
app-settings.jsonesa confirmación.
Qué se recompila al volver a ejecutar
La nueva ejecución recompila el código a partir del commit anterior. No reutiliza el artefacto binario original. Este comportamiento significa:
- Con los archivos de bloqueo de dependencias fijados (
package-lock.json,requirements.txt, etc.), el resultado es funcionalmente idéntico. - El tiempo de compilación es el mismo que una implementación normal. No es instantáneo.
- Las dependencias externas capturadas en tiempo de compilación (NuGet, npm, pip) deben estar disponibles.
Consideraciones sobre la reversión
Fija tus archivos de bloqueo de dependencias (
package-lock.json,requirements.txto versiones bloqueadas.csproj) en el control de código fuente. Los archivos de bloqueo anclados garantizan que volver a ejecutar una implementación genera una compilación funcionalmente idéntica independientemente de cuándo se produzca la nueva ejecución.La reejecución utiliza el YAML del flujo de trabajo o del pipeline de la confirmación original. Sin embargo, los secretos y las variables del pipeline se resuelven con sus valores actuales en el momento de la reejecución. Cuando se rotan los secretos entre la ejecución original y una reejecución, se utiliza el nuevo valor del secreto.
Una nueva ejecución restaura la aplicación implementada en un estado correcto conocido, pero no cambia el historial de Git. El HEAD de tu rama sigue apuntando al commit defectuoso.
Lo que no se restaura al volver a ejecutar:
- Configuración de recursos de Azure administrada fuera de su despliegue, incluidos los planes de alojamiento, la configuración de red y las asignaciones de identidad.
- Cambios en los datos o en el esquema de servicios posteriores, como bases de datos, colas de mensajes y almacenamiento.
- Valores secretos de Key Vault. Solo se mantienen las referencias de Key Vault en el control de código fuente. La rotación de secretos es una operación de Key Vault.
Pruebe periódicamente el proceso de reversión. No espere a que se produzca un incidente en producción para descubrir que algo no funciona.
Corregir la rama tras una reversión
Dado que la siguiente ejecución activada por un push vuelve a implementar el commit defectuoso, los demás desarrolladores que descarguen la rama seguirán viendo el código defectuoso. Debe corregir esta situación con una de estas acciones:
- Crea un commit de corrección que solucione el problema; se trata, en esencia, de una operación de avance.
- Realiza un
git revertpara deshacer el commit defectuoso creando un nuevo commit, lo que también es una acción de avance. - Directiva de rama que impide la combinación hasta corregir el problema.
Hasta que completes una de estas acciones, evita activar una nueva ejecución en esa rama. Para obtener instrucciones de validación, consulte Validar antes de la combinación.
Avanzar un despliegue
El roll forward consiste en enviar un nuevo commit para solucionar el problema. La implementación interrumpida permanece activa hasta que se implementa la corrección, por lo que esta estrategia funciona mejor cuando la aplicación puede tolerar un comportamiento degradado durante ese tiempo.
Crea un commit de corrección en tu rama. Esta corrección puede ser:
- Un hotfix que aborda directamente el problema.
- Un
git revert <bad-commit-sha>que cree un nuevo commit que deshaga los cambios erróneos. Aunquegit revertrevierte el código, se trata de un avance porque genera un nuevo commit y desencadena un nuevo despliegue.
Si la corrección también requiere cambios de configuración, actualiza la configuración de tu app (ya sea en
app-settings.jsono en tu plantilla de Bicep) en el mismo commit.Inserte la confirmación. Tu implementación compila y despliega automáticamente la corrección.
Validar antes de combinar
Independientemente de su estrategia de recuperación, valide y corrija los commits antes de fusionarlos en su rama de producción para evitar agravar el problema.
Estas recomendaciones se aplican tanto si realizas un roll forward de forma proactiva como si corriges la rama tras una reversión:
Utilice un entorno de prueba: dado que el plan de consumo flexible no admite actualmente ranuras de implementación, considere la posibilidad de implementar en una aplicación independiente del plan de consumo flexible para validar su corrección antes de fusionarla con la rama de producción.
Automatizar comprobaciones de estado: agregue un paso posterior a la implementación que llame a un punto de conexión de comprobación de estado en la aplicación y compruebe una respuesta positiva. En caso de fallo, considere la posibilidad de activar una nueva ejecución de la ejecución anterior que haya tenido éxito para revertir los cambios automáticamente.
Supervisión después de la implementación: configure alertas de Application Insights para la detección de regresión. La detección temprana reduce el impacto de una implementación incorrecta.