Pide tu presupuesto ya!
Cada entorno de prueba compartido que mantiene le cuesta a su equipo el doble: una vez en gasto de Azure y otra vez en horas de desarrollador perdidas en colas. Las matemáticas no son complicadas. Cinco desarrolladores que comparten un espacio de preparación significa que siempre hay cuatro esperando. Multiplique ese tiempo de inactividad por su costo de ingeniería por hora y el cuello de botella de la preparación se convertirá silenciosamente en la parte más costosa de su proceso de entrega.
Los entornos de vista previa efímeros solucionan este problema al darle a cada solicitud de extracción su propia implementación aislada y en vivo. El entorno gira cuando se abre el PR, ejecuta el código exacto de la sucursal y desaparece cuando se cierra el PR. Sin colas. Nada de “¿quién rompió la puesta en escena?” investigaciones. No hay una infraestructura siempre activa que queme dinero de la noche a la mañana.
Aplicaciones de contenedor de Azure (ACA) hace que esto sea práctico a través de su sistema de revisión y una función de enrutamiento llamada etiquetas de implementación. Conectarás un Azure DevOps canalización que crea un entorno de vista previa para cada PR, publica la URL en el hilo de PR y limpia todo automáticamente. Así es como.
Antes de comenzar, asegúrese de tener:
Verifique el modo de revisión de su aplicación Container:
az containerapp show \ --name myapp \ --resource-group preview-rg \ --query "properties.configuration.activeRevisionsMode" \ --output tsv
si regresa singlecambiar a multiple:
az containerapp revision set-mode \ --name myapp \ --resource-group preview-rg \ --mode multiple
ACA crea un nuevo revisión(una instantánea inmutable de su aplicación) cada vez que cambia la imagen o la configuración del contenedor. En el modo de revisión múltiple, se pueden ejecutar varias revisiones simultáneamente.
El problema de enrutamiento es sencillo: ¿cómo se envía un revisor a la revisión del PR sin afectar el tráfico de producción? Las etiquetas de revisión resuelven esto asignando un nombre a una revisión específica, lo que genera una URL dedicada:
“`texto sin formato
https://miaplicación—pr-42.
Traffic to this URL routes exclusively to the labeled revision. Your production URL keeps serving production. Zero interference. | Component | What It Does | | --- | --- | | Revision suffix (`--revision-suffix`) | Names the revision predictably (e.g., `myapp--pr-42`) | | Label (`--label`) | Generates the unique URL for direct access | | Traffic weight (0%) | Prevents the preview from receiving production traffic | --- ***Pro Tip: Label names must be lowercase alphanumeric with dashes only. Use ******`pr-<number>`****** as your convention—it's readable in the Azure portal and easy to match against PR IDs programmatically.*** --- ## Building the Pipeline Your `azure-pipelines.yml` needs three stages: build, deploy, and notify. Here's each piece. ### Build and Push the Container Image Tag images with the PR number so every revision traces back to its source:
disparador: ninguno
pr:
sucursales:
incluir:
– principal
variables:
prId: $(System.PullRequest.PullRequestId)
etapas:
– etapa: construir
trabajos:
– trabajo: BuildAndPush
piscina:
vmImagen: ‘ubuntu-último’
pasos:
– tarea: Docker@2
displayName: ‘Crear y enviar imagen’
entradas:
contenedorRegistry: ‘myACRConnection’
repositorio: ‘miaplicación’
comando: ‘buildAndPush’
Archivo Docker: ‘**/Archivo Docker’
etiquetas: ‘pr-$(prId)’
Using `pr-$(prId)` as the tag instead of `latest` forces ACA to recognize each push as a distinct image, which triggers a new revision. ### Deploy the Preview Revision
tarea: AzureCLI@2
displayName: ‘Implementar revisión de vista previa’
entradas:
azureSubscription: ‘myAzureServiceConnection’
tipo de script: ‘bash’
Ubicación del script: ‘inlineScript’
script en línea: |
ID_PR=$(ID_PR)
# Implementar una nueva revisión con una imagen específica de relaciones públicas
actualización de la aplicación contenedora az \
–nombre miaplicación \
–vista previa del grupo de recursos-rg \
–imagen myacr.azurecr.io/myapp:pr-$PR_ID \
–sufijo-revisión pr-$PR_ID
# Etiquetar la revisión para generar su URL única
etiqueta de revisión de az containerapp agregar \
–nombre miaplicación \
–vista previa del grupo de recursos-rg \
–etiqueta pr-$PR_ID \
–revisión miaplicación–pr-$PR_ID
The `--revision-suffix` parameter creates a predictable revision name (`myapp--pr-42`). The label generates the URL that reviewers will use. --- ***Reality Check: If you push multiple commits to the same PR, each triggers a new revision. The label moves to the latest revision automatically when you use ***[***`az containerapp update`***](https://learn.microsoft.com/cli/azure/containerapp#az-containerapp-update)*** with ******`--target-label`******. Your reviewers always see the most recent code at the same URL.*** --- ### Notify Reviewers With the Preview URL
- task: AzureCLI@2
displayName: 'Post preview URL to PR'
inputs:
azureSubscription: 'myAzureServiceConnection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
PR_ID=$(prId)
# Get the environment's default domain
ENV_DOMAIN=$(az containerapp env show \
--name my-env \
--resource-group preview-rg \
--query "properties.defaultDomain" \
--output tsv)
PREVIEW_URL="https://myapp---pr-$PR_ID.$ENV_DOMAIN"
# Post comment to PR thread
BODY=$(cat <<EOF
{"comments": [{"parentCommentId": 0, "content": "Preview environment ready: [$PREVIEW_URL]($PREVIEW_URL)", "commentType": 1}], "status": 1}
EOF
)
curl -s -X POST \
-H "Authorization: Bearer $SYSTEM_ACCESSTOKEN" \
-H "Content-Type: application/json" \
-d "$BODY" \
"$(System.CollectionUri)$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.Id)/pullRequests/$PR_ID/threads?api-version=7.0"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Your PR now has a clickable link to the live preview. QA, designers, and product managers can test without waiting for anyone to deploy to staging. ## Scale to Zero: Why This Costs Almost Nothing [ACA's scaling rules](https://learn.microsoft.com/azure/container-apps/scale-app) use [KEDA](https://keda.sh/) (Kubernetes Event-driven Autoscaling) to scale replicas based on HTTP traffic. Set minimum replicas to zero, and idle preview environments consume no compute:
actualización de la aplicación contenedora az \
–nombre miaplicación \
–vista previa del grupo de recursos-rg \
–réplicas mínimas 0 \
–max-réplicas 2
When a reviewer clicks the preview URL, KEDA detects the incoming request and scales from zero to one replica. The first request takes a few extra seconds for the cold start. Subsequent requests respond normally. | Scenario | Monthly Cost (illustrative) | | --- | --- | | Always-on [App Service](https://azure.microsoft.com/pricing/details/app-service/) (B1) | ~$55/environment | | ACA preview with 2 hours active testing/day | ~$0.16/day | | 20 PRs/month, each tested for 2 hours total | ~$3.20 total | *Estimates based on *[*Azure Container Apps pricing*](https://azure.microsoft.com/pricing/details/container-apps/)* and *[*App Service pricing*](https://azure.microsoft.com/pricing/details/app-service/)*. Actual costs vary by region and configuration.* The [ACA free grant](https://azure.microsoft.com/pricing/details/container-apps/) covers a generous monthly allotment of requests and compute seconds. Most teams running preview environments stay within the free tier entirely. ## Cleaning Up After PR Closure Azure DevOps does not natively trigger pipelines when a PR closes or merges. You need a cleanup mechanism to deactivate stale preview revisions. ### Option A: Scheduled Cleanup Pipeline Run a nightly pipeline that compares active revisions against open PRs:
REVISIONS=$(az lista de revisiones de aplicaciones contenedoras \
–nombre miaplicación \
–vista previa del grupo de recursos-rg \
-consulta “[?contains(name, ‘pr-‘) && properties.active].nombre” \
–salida tsv)
OPEN_PRS=$(az repos pr lista \
–repositorio miaplicación \
–estado activo \
-consulta “[].pullRequestId”\
–salida tsv)
para rev en $REVISIONS; hacer
si [[ $rev =~ pr-([0-9]+) ]]; entonces
PR_NUM=”${BASH_REMATCH[1]}”
si ! eco “$OPEN_PRS” | grep -qw “$PR_NUM”; entonces
echo “Desactivando $rev (PR #$PR_NUM está cerrado)”
revisión de la aplicación contenedora az desactivar \
–nombre miaplicación \
–vista previa del grupo de recursos-rg \
–revisión “$rev”
fi
fi
hecho
Schedule this in your pipeline with a [cron trigger](https://learn.microsoft.com/azure/devops/pipelines/process/scheduled-triggers):
horarios:
– cron: ‘0 2 * * *’
displayName: ‘Limpieza de vista previa nocturna’
sucursales:
incluir:
– principal
siempre: cierto
“`
Configurar un Enlace de servicio Azure DevOps para activarse en el evento “Solicitud de extracción actualizada”. Apunte a una función de Azure que verifica si el estado del PR cambió a “completado” o “abandonado” y luego desactiva la revisión correspondiente.
Este enfoque reacciona más rápido que la limpieza programada, pero requiere mantener una función de Azure.
Ganancia rápida: ACA admite una --max-inactive-revisions bandera durante la creación de la aplicación. Configúrelo en 50 o menos para evitar alcanzar el límite de 100 revisiones incluso si su secuencia de comandos de limpieza omite algunas.
Los entornos de vista previa necesitan datos. Tres estrategias manejan esto en diferentes niveles de complejidad:
Base de datos compartida, esquemas aislados: Cada entorno de vista previa crea una base de datos o esquema llamado pr_<number>. Su canalización ejecuta migraciones durante la implementación y descarta el esquema durante la limpieza. Gastos generales bajos, buen aislamiento.
Base de datos en contenedores: Ejecute PostgreSQL o SQL Server como contenedor con sidecar en la misma aplicación contenedora. Los datos son efímeros: desaparecen cuando se desactiva la revisión. Lo mejor para pruebas de integración que generan sus propios datos.
Instantánea de producción: Restaure una copia anónima de los datos de producción para realizar pruebas realistas. Mayor costo y complejidad, pero necesario para pruebas de rendimiento o validación de migración de datos.
Comience con el enfoque de base de datos compartida. Pase a las instantáneas solo cuando sus requisitos de prueba exijan volúmenes de datos representativos de la producción.
ACA hace cumplir una Límite de 100 revisiones por aplicación de contenedor (activa e inactiva combinadas). Los equipos de alta velocidad que abren docenas de relaciones públicas diariamente lograrán esto. Limpieza agresiva y --max-inactive-revisions La bandera son tus principales defensas.
Arranques en frio normalmente toma unos segundos al escalar desde cero. Establezca expectativas con sus revisores. Una nota en el comentario de relaciones públicas (“La primera carga tarda unos segundos”) evita informes de errores innecesarios sobre enlaces de vista previa “rotos”.
Azure DevOps políticas de sucursales con validación de compilación no disparar pr: Activadores YAML: en su lugar, utilizan su propio mecanismo de política de compilación. Si utiliza políticas de sucursal para la validación de relaciones públicas, configure la política de compilación para que apunte a su canal de vista previa en lugar de depender de pr: desencadenantes.
Ahora tiene una canalización que crea entornos de vista previa aislados para cada PR, publica la URL para los revisores, escala a cero cuando está inactivo y se limpia automáticamente. Su entorno de puesta en escena simplemente se volvió redundante.
El siguiente paso inmediato: ampliar esto a múltiples servicios. El patrón de canalización es idéntico: solo cambian el nombre de la aplicación y la ruta del registro del contenedor. Si su aplicación tiene un frontend y un backend API, cree entornos de vista previa para ambos y conéctelos usando DNS interno de aplicaciones de contenedor.
Tu equipo deja de esperar la puesta en escena. Sus revisores prueban cada cambio de forma aislada. Su factura de Azure baja. Ese es todo el argumento a favor de los entornos efímeros, y usted acaba de construir uno.
Leave a comment