D/ DJANGO CON CRITERIO

UNIDAD 8 · AZURE Y DJANGO: CONFIGURACIÓN Y DESPLIEGUE

Variables de producción y contrato de configuración

Traslada nombres de configuración a Azure sin subir el .env.

Ilustración: La caja de variables
La caja de variables

CAPÍTULO 9 · El mismo proyecto llega a Azure

El servidor recibe su configuración, no la del PC

Crear los recursos no hace que Django conozca automáticamente sus conexiones o su dominio. El proyecto solo puede utilizar las variables que su código lee. Aquí reaparece el contrato que definimos al separar entornos: mismos nombres y responsabilidades, valores distintos según el destino.

Configuramos la selección de production, la clave del servicio, los hosts y las conexiones requeridas. Si la aplicación usa MSAL, incorporamos también los valores de su registro y la URI de retorno de producción. Cada variable tiene un propósito verificable. Evitamos comprobarla mostrando secretos y distinguimos una opción propia del proyecto de una función que se activa en el portal.

El servidor ya puede recibir los datos que necesita al arrancar. Pero aún debe saber qué proceso ejecutar. El comando que utilizábamos para ver la primera página local nos sirvió durante el aprendizaje; ahora tenemos que elegir la entrada apropiada para el comportamiento HTTP o de tiempo real que construimos.

Leer esta parte dentro del relato completo →

DEL RELATO A LA PRÁCTICA

Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.

LABORATORIO DE CONFIGURACIÓN

Prepara tu estación de despliegue

Cambia el entorno, el servidor y la identidad para comparar sus responsabilidades.

Isla con servidores y una llave

Simulación didáctica. Los valores son ejemplos: no crea recursos, no inicia sesión ni publica archivos. Sin JavaScript, consulta la tabla y los pasos de la lección.

MIRA · CONECTA · COMPRENDE

La caja de variables

La caja de variables1. Contrato: Define nombres y tipos; 2. Valores: Separa secretos por entorno; 3. Azure: Inyecta al proceso; 4. Verificación: Revisa sin exponer claves01ContratoDefine nombres y tipos02ValoresSepara secretos por entorno03AzureInyecta al proceso04VerificaciónRevisa sin exponer claves

Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.

Selecciona una pieza para destacar su responsabilidad.

Leer la explicación del mapa
  1. Contrato. Define nombres y tipos
  2. Valores. Separa secretos por entorno
  3. Azure. Inyecta al proceso
  4. Verificación. Revisa sin exponer claves
Descargar gráfico SVG ↓

¿Para qué sirve?

El mismo código debe recibir valores diferentes en Azure. Si el paquete lleva credenciales locales, puede conectarse a la base equivocada.

El concepto, explicado

Mantén una matriz por entorno: nombre, finalidad, obligatoriedad y quién lo administra. Los nombres propios del ejemplo son ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, SECRET_KEY y DB_*. Si tu base.py lee DJANGO_ALLOWED_HOSTS_PROD, usa ese contrato o renómbralo en ambos sitios.

En App Service, configura los valores en Variables de entorno / configuración de la aplicación. El proceso Python los recibe al iniciar. Para secretos administrados puedes usar referencias de Key Vault con permisos de lectura de la identidad administrada.

DJANGO_SETTINGS_MODULE=config.settings.production selecciona el módulo. ALLOWED_HOSTS contiene hosts sin esquema; CSRF_TRUSTED_ORIGINS contiene orígenes con https://. La clave de producción debe ser distinta a desarrollo.

Cuando uses slots, marca como propias del slot las conexiones e identidades que deben permanecer con el entorno. Un swap de código no debería trasladar la contraseña de PROD a una base DEV.

La ruta manual de este curso entrega estáticos previamente construidos. Mantén SCM_DO_BUILD_DURING_DEPLOYMENT=true para instalar dependencias Linux y DISABLE_COLLECTSTATIC=true para no volver a recolectarlos. Esta última opción solo es válida cuando verificaste que el ZIP contiene el manifiesto y todos los archivos de STATIC_ROOT.

Los nombres deben coincidir con el código que los lee: el proyecto de referencia usa DJANGO_ALLOWED_HOSTS_PROD; el ejemplo público usa ALLOWED_HOSTS. En ambos casos, DJANGO_SETTINGS_MODULE selecciona config.settings.production. Un nombre inventado en el portal no modifica settings automáticamente.

Contrato por entorno

NombreLocal / DEVAzure / PROD
DJANGO_SETTINGS_MODULEconfig.settings.developmentconfig.settings.production
SECRET_KEYValor exclusivo localSecreto obligatorio distinto
ALLOWED_HOSTSlocalhost,127.0.0.1Host real sin https://
CSRF_TRUSTED_ORIGINSSegún el origen de pruebahttps://host-real si corresponde
DB_HOST / DB_NAME / DB_PORTBase de prácticaBase productiva y puerto
DB_USER / DB_PASSWORDRol de laboratorioRuntime limitado, secreto administrado
AZURE_TENANT_ID / AZURE_CLIENT_IDRegistro DEV si hay MSALRegistro PROD si hay MSAL
AZURE_CLIENT_SECRETCredencial DEV fuera de GitCredencial PROD de servidor
AZURE_REDIRECT_URIhttp://localhost:8000/aad/callbackhttps://host-real/aad/callback
USE_EASYAUTHfalse para MSAL propiofalse para MSAL, true solo para el adaptador Easy Auth
SCM_DO_BUILD_DURING_DEPLOYMENTNo se necesita en runservertrue para ZIP de código con Oryx

Implementación paso a paso

  1. Anota las variables que realmente lee tu código.
  2. Carga secretos por el canal aprobado del equipo; evita dejarlos en comandos guardados o capturas.
  3. Configura el módulo de producción y los hosts.
  4. Configura DB_* con usuario runtime limitado y conectividad comprobada.
  5. Reinicia si corresponde y revisa solo presencia y parámetros no secretos.

Ejemplo en SensorHub

# PowerShell: ejemplo de parámetros no secretos
$rg = "rg-sensorhub-dev"
$app = "app-sensorhub-dev"
$hostName = az webapp show -g $rg -n $app --query defaultHostName -o tsv
az webapp config appsettings set -g $rg -n $app --settings `
  DJANGO_SETTINGS_MODULE=config.settings.production `
  "ALLOWED_HOSTS=$hostName" `
  "CSRF_TRUSTED_ORIGINS=https://$hostName" `
  SCM_DO_BUILD_DURING_DEPLOYMENT=true --output none
# SECRET_KEY y DB_PASSWORD: cargar por gestión segura del entorno.
# Comprobación en Python, sin volcar valores:
# assert os.environ.get("SECRET_KEY"), "Falta SECRET_KEY"
# Ruta manual con estáticos ya incluidos en SensorHub/staticfiles:
# SCM_DO_BUILD_DURING_DEPLOYMENT=true  -> instala dependencias en Linux
# DISABLE_COLLECTSTATIC=true           -> conserva los estáticos ya construidos
# Arranque WSGI: gunicorn --chdir SensorHub config.wsgi:application --bind 0.0.0.0:8000
# DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT: solo si DATABASES los lee.
# DB_SSLROOTCERT: ruta al certificado CA en el servidor, si usas verify-full.
# MSAL propio: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_REDIRECT_URI.
# Academia pública: no requiere MSAL ni PostgreSQL para abrir las lecciones.

Cómo leer el ejemplo

  • El acento grave continúa una línea PowerShell; no debe tener espacios después.
  • --output none evita imprimir la respuesta completa de app settings.
  • SCM_DO_BUILD_DURING_DEPLOYMENT habilita la construcción del ZIP de código.

Error habitual

No imprimas appsettings completos para mostrar que funciona. Son configuración sensible y pueden contener credenciales.

05 / PRACTICAR

Tu turno

¿Por qué ALLOWED_HOSTS=https://miapp... es una configuración incorrecta?

Ver solución orientativa

ALLOWED_HOSTS compara nombres de host, sin protocolo. El origen completo pertenece a CSRF_TRUSTED_ORIGINS.

Cómo sabes que funciona

  • PROD carga production.py y DEBUG=False.
  • El paquete no contiene .env y los secretos no aparecen en logs.

Para profundizar

Documentación oficial para comprobar configuración, permisos y condiciones vigentes. Revisión del tema: 11 de octubre de 2026.

CONTINUAR LA EXPERIENCIA

El siguiente paso del recorrido:

Comando de arranque: Gunicorn o Daphne →Continuar en modo relato