Cuando el vuelo CA-1187 se retrasa tres horas, Contoso Airlines tiene que hacer siempre lo mismo: buscar en db-reservas los pasajeros afectados, enviarles un correo y un mensaje de texto, publicar el aviso en el canal del equipo de operaciones y abrir un incidente en el sistema de soporte. Nada de eso es lógica de negocio compleja; es pegar sistemas entre sí. Escrito como código serían cuatro integraciones con sus autenticaciones, sus formatos y sus reintentos, mantenidas por Diego Salas. Y hay un detalle incómodo: quien conoce el proceso de verdad es el equipo de operaciones, que no programa.
Azure Logic Apps existe para eso. Es un motor de flujos de trabajo con más de mil conectores listos, que se diseña visualmente y se guarda como una definición JSON versionable. Esta lección enseña a construir ese flujo real, a gestionar sus errores, a desplegarlo entre entornos —donde está el problema clásico, las conexiones— y a saber cuándo toca una aplicación lógica y cuándo no.
Contenido
- Qué es una aplicación lógica y en qué se diferencia de Functions
- Consumo frente a Estándar
- Anatomía: desencadenador, acciones y conectores
- El flujo de retraso de vuelo, paso a paso
- La definición JSON subyacente
- Control de flujo: condiciones, bucles, ámbitos y paralelismo
- Gestión de errores: reintentos, ejecución posterior y compensación
- Conexiones y su autenticación
- Supervisión y depuración de una ejecución fallida
- Integración con el resto de la plataforma
- Despliegue con Bicep y el problema de las conexiones
- Coste por acción ejecutada
- Logic Apps, Functions o Data Factory
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Qué es una aplicación lógica y en qué se diferencia de Functions
Una aplicación lógica es un flujo de trabajo: un desencadenador y una secuencia de acciones conectadas, donde la salida de cada paso alimenta al siguiente. No compilas nada ni gestionas dependencias.
| Azure Functions | Azure Logic Apps | |
|---|---|---|
| Cómo se construye | Escribiendo código | Diseñador visual (+ JSON) |
| Quién lo mantiene | Desarrolladores | Desarrolladores y perfiles de negocio |
| Punto fuerte | Lógica y transformación a medida | Conectar sistemas ya existentes |
| Integrarse con SaaS | Escribir el cliente HTTP | Conector listo |
| Coste | Por ejecución y GB-s | Por acción ejecutada |
| Depuración | Registros y trazas | Historial visual con datos de cada paso |
| Cuándo brilla | Cálculo, algoritmo, transformación compleja | Orquestación entre servicios y esperas humanas |
La regla es simple: si el problema es «hacer algo complicado», Functions; si el problema es «hablar con seis sistemas distintos», Logic Apps. Y no compiten: el flujo de Contoso llamará a una función de 06-03 para la parte que sí requiere código.
- Consumo frente a Estándar
| Consumo | Estándar | |
|---|---|---|
| Motor | Multiinquilino compartido | Dedicado, sobre el tiempo de ejecución de Functions |
| Precio | Por acción ejecutada | Por plan de hospedaje (fijo) |
| Flujos por recurso | Uno | Varios en la misma aplicación |
| Integración con red virtual | No (requiere ISE) | Sí, con puntos privados |
| Ejecución y depuración en local | No | Sí, con VS Code |
| Conectores integrados | Pocos | Muchos más, sin coste por acción |
| Cuándo | Flujos esporádicos y sencillos | Producción, alto volumen, red privada |
Contoso elige Estándar para logic-contoso-retrasos-pro por dos razones concretas: necesita alcanzar pe-sql-reservas por punto privado, y con volumen alto el precio fijo es más predecible que pagar por acción cuando un solo retraso puede desencadenar cientos de acciones.
- Anatomía: desencadenador, acciones y conectores
- Desencadenador: qué inicia el flujo. Puede ser una petición HTTP, una programación, o un conector que sondea un sistema («cuando llegue un correo», «cuando se cree una fila»).
- Acción: cada paso posterior. Consulta datos, llama a una API, envía un mensaje, decide, itera.
- Conector integrado: se ejecuta dentro del motor. Rápido, sin coste por acción en el nivel Estándar: HTTP, Service Bus, Azure Functions, SQL Server, control de flujo.
- Conector gestionado: un envoltorio alojado por Microsoft sobre un servicio externo: Office 365, Salesforce, SAP, Twilio, ServiceNow, Slack. Se factura por acción y requiere una conexión con sus credenciales.
El valor real de Logic Apps es ese catálogo de más de mil conectores. Integrar ServiceNow a mano son días de trabajo —autenticación, esquema, reintentos, paginación— y aquí es arrastrar una acción. Ese es todo el argumento, y es un argumento fuerte.
- El flujo de retraso de vuelo, paso a paso
graph TD
T["Desencadenador HTTP:<br/>POST /retraso {vuelo, minutos}"] --> V{"¿minutos > 60?"}
V -->|No| FIN["Registrar y terminar"]
V -->|Si| SQL["SQL: pasajeros afectados<br/>de db-reservas"]
SQL --> FE["Para cada pasajero (en paralelo)"]
FE --> COR["Office 365: correo"]
FE --> SMS["Twilio: mensaje"]
SQL --> OPS["Teams: aviso al canal<br/>de operaciones"]
SQL --> INC["ServiceNow: abrir incidente"]
SQL --> FUN["Function CalcularCompensacion<br/>(06-03)"]
FUN --> INC
Los pasos, en orden:
- Desencadenador «Cuando se recibe una petición HTTP». Genera una URL con una firma; el sistema de operaciones publica ahí
{ "vuelo": "CA-1187", "minutos": 180, "fecha": "2026-08-15" }. Se define un esquema JSON de la carga para que los campos aparezcan como fichas seleccionables en los pasos siguientes. - Condición: si el retraso no supera 60 minutos, no hay obligación de notificar. Se registra y termina.
- Acción SQL «Ejecutar consulta» contra
db-reservas, con el número de vuelo y la fecha como parámetros —nunca concatenados en el texto de la consulta, que sería inyección SQL—, devolviendo localizador, nombre, correo y teléfono. - Llamar a la función
CalcularCompensacionde 06-03 con el retraso y la ruta. Ese cálculo depende del reglamento europeo, tiene sus casos especiales y es código: no se hace con acciones visuales. - Bucle
for eachsobre los pasajeros, en paralelo, con el envío de correo (Office 365) y de mensaje (Twilio) dentro. - Aviso al canal de operaciones en Teams, con el resumen y el número de afectados.
- Abrir el incidente en ServiceNow con el importe de compensación calculado.
- La definición JSON subyacente
El diseñador es una vista sobre un fichero. Esto importa: la aplicación lógica es código versionable que vive en contoso-infra y pasa por revisión como cualquier cambio (05-02).
{
"definition": {
"triggers": {
"PeticionRetraso": {
"type": "Request", "kind": "Http",
"inputs": { "schema": { "type": "object", "properties": {
"vuelo": { "type": "string" },
"minutos": { "type": "integer" },
"fecha": { "type": "string" } } } }
}
},
"actions": {
"SiSuperaUnaHora": {
"type": "If",
"expression": { "greater": [ "@triggerBody()?['minutos']", 60 ] },
"actions": {
"ObtenerPasajeros": {
"type": "ApiConnection",
"inputs": {
"host": { "connection": { "name": "@parameters('$connections')['sql']['connectionId']" } },
"method": "post", "path": "/datasets/default/query/sql",
"body": {
"query": "SELECT localizador, nombre, correo, telefono FROM Reservas WHERE numeroVuelo=@vuelo AND fecha=@fecha",
"parameters": { "vuelo": "@triggerBody()?['vuelo']",
"fecha": "@triggerBody()?['fecha']" } }
},
"runAfter": {}
},
"PorCadaPasajero": {
"type": "Foreach",
"foreach": "@body('ObtenerPasajeros')?['resultsets']['Table1']",
"runtimeConfiguration": { "concurrency": { "repetitions": 20 } },
"actions": { "EnviarCorreo": { "type": "ApiConnection", "inputs": { } } },
"runAfter": { "ObtenerPasajeros": [ "Succeeded" ] }
}
}
}
}
}
}Tres piezas que conviene reconocer:
@triggerBody()?['minutos']es el lenguaje de expresiones. El?es el acceso seguro: si el campo no viene, devuelve nulo en lugar de romper el flujo. Úsalo siempre con datos externos.runAfteres lo que define el orden real de ejecución, no la posición visual. Un paso conrunAftervacío arranca en cuanto la rama empieza; dos acciones con el mismorunAfterse ejecutan en paralelo.concurrency.repetitionslimita cuántas iteraciones del bucle corren a la vez. Sin ese límite, un vuelo de 300 pasajeros dispara 300 llamadas simultáneas a Twilio y provoca limitación de solicitudes.
- Control de flujo: condiciones, bucles, ámbitos y paralelismo
- Condición (
If) con dos ramas, ySwitchcuando hay varios casos discretos, como el tipo de incidencia. For each: itera sobre una colección, por defecto en paralelo con 20 repeticiones simultáneas. Si el orden importa, hay que forzar la concurrencia a 1.Until: repite hasta que se cumple una condición o se agota un contador. Es el patrón de sondeo —«consultar el estado del reembolso cada 5 minutos hasta que esté aprobado o pasen 2 horas»—. Pon siempre un límite de iteraciones y de tiempo, o tienes un bucle infinito facturable.- Ámbito (
Scope): agrupa acciones en un bloque que tiene su propio estado agregado. Es la base de la gestión de errores del apartado siguiente: funciona como untry. - Ramas paralelas: dos acciones con el mismo
runAfterse ejecutan a la vez. Contoso lo usa para que el aviso a Teams y el incidente de ServiceNow no esperen al bucle de pasajeros.
- Gestión de errores: reintentos, ejecución posterior y compensación
Tres capas, de la más automática a la más manual.
Directiva de reintentos. Cada acción la lleva y por defecto reintenta 4 veces con espera exponencial ante errores transitorios (429 y 5xx). Se ajusta por acción:
"retryPolicy": { "type": "exponential", "count": 5,
"interval": "PT10S", "maximumInterval": "PT1H" }Con "type": "none" se desactiva, y hay un caso en que hay que desactivarlo: cuando la acción no es idempotente. Reintentar un cargo en la pasarela de pago cobra dos veces. Es la misma lección de 06-03, aquí en versión visual.
Acciones de ejecución posterior. El runAfter puede condicionarse a Failed, TimedOut o Skipped, no solo a Succeeded. Ese es el catch:
"NotificarFalloIntegracion": {
"type": "ApiConnection",
"runAfter": { "AmbitoNotificaciones": [ "Failed", "TimedOut" ] },
"inputs": { }
}Combinado con un ámbito, el patrón try/catch queda: ámbito AmbitoNotificaciones con los envíos dentro, y una acción posterior que se ejecuta solo si el ámbito falló, avisando al equipo con @result('AmbitoNotificaciones'), que devuelve el detalle de qué acción concreta reventó.
Compensación. No hay transacciones distribuidas: si el correo se envió y el mensaje falló, el correo no se puede «deshacer». El patrón es añadir acciones que corrigen —marcar el aviso como parcial, encolar un reenvío, abrir un incidente de revisión manual—. Diséñalo explícitamente, porque el flujo va a fallar a la mitad tarde o temprano.
- Conexiones y su autenticación
Una conexión es un recurso de Azure independiente del flujo que guarda cómo autenticarse contra un sistema. Y son de tres tipos:
| Tipo | Ejemplo | Riesgo |
|---|---|---|
| Identidad administrada | SQL Server, Blob, Key Vault, Service Bus | Ninguno: sin secretos, y es la opción correcta |
| Entidad de servicio | APIs de Azure con permisos concretos | Secreto que rotar |
| OAuth delegado | Office 365, Teams, Salesforce | Atado a una persona: si se va, el flujo muere |
Contoso usa identidad administrada siempre que el conector la admite: id-contoso-api-pro accede a db-reservas y a kv-contoso-pro sin credenciales. Para los conectores que exigen OAuth delegado, la regla del equipo es autorizarlos con una cuenta de servicio del dominio —[email protected]— y nunca con la cuenta personal de Marta o Diego. Es un error que se paga meses después, cuando alguien cambia de puesto y los flujos empiezan a fallar con 401.
- Supervisión y depuración de una ejecución fallida
El historial de ejecuciones es la mejor herramienta de diagnóstico de todo el módulo. Cada ejecución muestra el flujo dibujado con cada paso en verde o rojo y, al pinchar en un paso, las entradas y las salidas exactas de esa ejecución concreta: el JSON que entró, el que salió y el error literal.
El proceso de depuración práctico: abrir la ejecución fallida, localizar el primer paso en rojo —los siguientes suelen ser consecuencia—, leer sus entradas para ver qué datos recibió realmente, y contrastar con lo que esperabas. La mayoría de los fallos son de forma de los datos: un campo nulo que se asumía presente, una fecha en otro formato, una colección vacía. Corregido el problema en el sistema de origen, la reejecución relanza esa misma ejecución con los mismos datos de entrada, sin tener que reproducir el evento original.
Se completa con el envío de diagnósticos a log-contoso-pro para consultar con KQL y crear alertas sobre el número de ejecuciones fallidas (07-01 y 07-02).
- Integración con el resto de la plataforma
Aquí es donde Logic Apps deja de ser una herramienta suelta:
- Desde una alerta de Azure Monitor (07-01): un grupo de acciones puede invocar la URL del desencadenador HTTP. Así, «la latencia de
app-contoso-reservas-prosupera 2 s» deja de ser un correo y pasa a ser un flujo que abre el incidente, avisa al canal y adjunta el enlace al panel. - Desde Defender for Cloud (04-05): sus automatizaciones de flujo de trabajo disparan aplicaciones lógicas ante una alerta de seguridad, para aislar un recurso o notificar al responsable de guardia.
- Desde Event Grid (06-05): reaccionar a eventos de la plataforma sin escribir nada.
- Llamando a una función de 06-03 con el conector integrado de Azure Functions, para la lógica que sí es código. Esta combinación es la buena: Logic Apps orquesta, Functions calcula.
- Despliegue con Bicep y el problema de las conexiones
El flujo se despliega como cualquier otro recurso desde contoso-infra, con el pipeline de infraestructura de 05-06:
resource flujoRetrasos 'Microsoft.Logic/workflows@2019-05-01' = {
name: 'logic-contoso-retrasos-${entorno}'
location: ubicacion
identity: { type: 'UserAssigned', userAssignedIdentities: { '${idIdentidad}': {} } }
tags: etiquetasComunes
properties: {
state: 'Enabled'
definition: json(loadTextContent('flujos/retrasos.json'))
parameters: {
'$connections': { value: { sql: {
connectionId: conexionSql.id
connectionName: conexionSql.name
id: subscriptionResourceId('Microsoft.Web/locations/managedApis',
ubicacion, 'sql') } } }
}
}
}Y aquí está el problema clásico. La definición del flujo se promociona limpiamente entre entornos, pero las conexiones no: cada entorno tiene las suyas, con identificadores distintos, y las de OAuth delegado necesitan que un humano pulse «Autorizar» en el portal la primera vez. Si no se separan, el despliegue en producción arrastra la conexión de desarrollo y el flujo acaba consultando db-reservas del entorno equivocado. La disciplina que lo evita:
- La definición del flujo nunca lleva identificadores de conexión codificados: van en el parámetro
$connections. - Las conexiones se declaran como recursos aparte, por entorno, con su
.bicepparam. - Las de identidad administrada se automatizan del todo; las de OAuth se autorizan una vez con la cuenta de servicio del dominio y se documenta ese paso manual.
- Coste por acción ejecutada
En el nivel Consumo se paga cada acción ejecutada, y el matiz es que las iteraciones de un bucle cuentan por separado. Haz la cuenta del flujo de Contoso: un vuelo de 250 pasajeros ejecuta 2 acciones por pasajero, o sea 500, más una decena del resto. Cinco retrasos al día son 2.500 acciones diarias. Con céntimos por cada mil acciones parece nada, pero el patrón que dispara la factura sin avisar es siempre el mismo: un desencadenador de sondeo cada minuto —43.200 comprobaciones al mes aunque no pase nada—, o un Until mal acotado, o un bucle anidado que multiplica.
Las medidas: usar desencadenadores de notificación en lugar de sondeo cuando el sistema lo permite (webhook o Event Grid), espaciar el sondeo a lo que de verdad se necesita, acotar los Until con contador y tiempo máximo, y en volúmenes altos pasar al nivel Estándar, donde el coste es un plan fijo y los conectores integrados no se facturan por acción.
- Logic Apps, Functions o Data Factory
| Logic Apps | Azure Functions | Data Factory (03-06) | |
|---|---|---|---|
| Propósito | Orquestar e integrar sistemas | Ejecutar lógica a medida | Mover y transformar datos a escala |
| Unidad de trabajo | Un evento de negocio | Un evento o petición | Un lote de millones de filas |
| Construcción | Diseñador visual + JSON | Código | Canalizaciones y flujos de datos |
| Conectores a SaaS | Más de mil | Los que escribas | Muchos, orientados a datos |
| Esperas humanas | Sí, nativas | Con Durable Functions | No |
| Caso de Contoso | Avisar por retraso de vuelo | Generar el PDF de la tarjeta | Cargar stlagocontosopro cada noche |
La frontera con Data Factory se resuelve con una pregunta: ¿el flujo trata un caso o un conjunto? Notificar a los pasajeros de un vuelo es un caso: Logic Apps. Cargar 40 millones de registros de embarque en la capa bronce es un conjunto: Data Factory.
Errores Comunes y Consejos
- Autorizar conexiones OAuth con una cuenta personal. El día que esa persona cambia de puesto, los flujos fallan con 401. Cuenta de servicio del dominio.
- Codificar identificadores de conexión en la definición. Rompe la promoción entre entornos. Parámetro
$connections. - Concatenar valores en una consulta SQL. Inyección SQL de manual. Usa parámetros.
- Dejar el
for eachcon la concurrencia por defecto cuando llama a una API con límite. 300 llamadas simultáneas provocan limitación y fallos en cascada. - Reintentar acciones no idempotentes. Un cargo reintentado se cobra dos veces. Desactiva la directiva en esos pasos.
- Un
Untilsin límite de iteraciones y de tiempo. Bucle infinito que además factura. - Sondear cada minuto por comodidad. Es la causa número uno de facturas sorpresa en el nivel Consumo.
- Consejo: nombra las acciones con lo que hacen (
ObtenerPasajerosAfectados), no con el nombre por defecto. Las expresiones referencian ese nombre y renombrar después las rompe. - Consejo: si el flujo tiene más de 30 acciones o mucha lógica condicional, la lógica pertenece a una función. El diseñador visual deja de ayudar cuando el flujo parece un plato de espaguetis.
Ejercicios
Ejercicio 1. Contoso Millas necesita un flujo mensual que calcule el nivel de fidelidad de cada socio, envíe un correo a quienes suben de nivel y publique el resumen en el canal del equipo comercial.
- Elige nivel (Consumo o Estándar) y desencadenador, y justifícalo.
- Enumera las acciones con su control de flujo, indicando dónde llamarías a una función y por qué.
- Indica las etiquetas obligatorias y estima el orden de magnitud del coste si hay 80.000 socios y 3.000 suben de nivel.
Ejercicio 2. Este flujo falla: la acción CargarPasaporte sube un documento al almacenamiento, ActualizarReserva marca el check-in en db-reservas, y EnviarConfirmacion avisa al pasajero. Ayer, ActualizarReserva falló por un tiempo de espera agotado y hoy hay pasaportes cargados de reservas que figuran sin check-in.
- Explica por qué falló, incluyendo qué hicieron los reintentos.
- Rediseña el flujo con ámbitos, ejecución posterior y compensación.
- ¿En qué se diferencia esto de una transacción y qué garantía puedes dar de verdad?
Ejercicio 3. Para cada caso elige Logic Apps, Functions o Data Factory: (a) al recibir un correo de un proveedor con un CSV adjunto, validarlo y abrir un incidente si tiene errores; (b) recalcular cada noche las tarifas de 12 millones de combinaciones origen-destino; (c) al confirmarse un pago, generar la factura en PDF con las reglas fiscales de siete países.
Soluciones
Solución 1:
- Consumo con desencadenador de programación mensual: se ejecuta una vez al mes, no necesita red virtual y el precio fijo del nivel Estándar no se justifica para doce ejecuciones al año.
- Programación → llamar a la función
CalcularNivelescon el lote de socios →for eachsobre los que suben de nivel, con concurrencia limitada, enviando el correo dentro → aviso a Teams con el resumen. El cálculo del nivel va en una función porque son reglas de negocio con umbrales, casos especiales y vigencias: eso es código, se prueba con pruebas unitarias y no se mantiene con acciones visuales. Además, procesar 80.000 socios paso a paso en el diseñador sería lentísimo y carísimo en acciones. entorno,proyecto=contoso-millas,centro-coste=CC-2077ypropietario. El coste depende de la clave del diseño: si la evaluación se hace dentro de la función, se facturan del orden de 3.000 iteraciones más una decena de acciones, es decir, unos pocos miles de acciones al mes: céntimos. Si en cambio se iterara sobre los 80.000 socios en el flujo con dos acciones cada uno, serían 160.000 acciones mensuales. La lección está ahí: el bucle en el sitio equivocado multiplica la factura por cincuenta.
Solución 2:
ActualizarReservaagotó su tiempo de espera contradb-reservas. La directiva de reintentos por defecto lo reintentó cuatro veces con espera exponencial y, al seguir fallando, la acción quedó enFailed; comoEnviarConfirmacionteníarunAfter: Succeeded, no se ejecutó y el flujo terminó fallido. PeroCargarPasaporteya se había completado, y nada lo revirtió: de ahí los documentos huérfanos.- Envolver
CargarPasaporteyActualizarReservaen un ámbitoAmbitoCheckIn. Añadir una acción conrunAfter: { AmbitoCheckIn: ["Failed","TimedOut"] }que ejecute la compensación: marcar el documento cargado como pendiente de conciliación, encolar un reintento diferido encola-emision-tarjetasy abrir un incidente con@result('AmbitoCheckIn').EnviarConfirmacionse mantiene conrunAfter: Succeededsobre el ámbito, para que el pasajero solo reciba la confirmación si todo salió bien. - Una transacción daría atomicidad: o todo o nada, con reversión automática. Aquí no la hay, porque los sistemas son independientes y no comparten un coordinador. Lo que puedes garantizar es consistencia final con compensación: cada efecto parcial queda registrado y hay un camino explícito que lo corrige o lo escala a un humano. La diferencia práctica es que existe una ventana en la que el sistema es incoherente, y el diseño tiene que aceptarla y hacerla visible en lugar de fingir que no existe.
Solución 3: (a) Logic Apps: el desencadenador de correo, el adjunto y la apertura del incidente son tres conectores listos, y el flujo es de integración pura. (b) Data Factory: es un conjunto masivo procesado por lotes; hacerlo con acciones de flujo sería absurdo en coste y tiempo. (c) Functions: reglas fiscales de siete países más generación de PDF es lógica compleja y código probable; a lo sumo, una aplicación lógica invoca esa función como parte de un flujo mayor.
Conclusión
Sabes qué es una aplicación lógica y en qué se diferencia de una función: flujo visual frente a código, integrar frente a calcular, coste por acción frente a coste por ejecución, y que la combinación buena es que Logic Apps orquesta y Functions calcula. Distingues Consumo de Estándar por motor, precio, red virtual, número de flujos y ejecución local, y sabes por qué Contoso eligió Estándar para logic-contoso-retrasos-pro. Dominas la anatomía —desencadenador, acciones, conectores integrados frente a gestionados— y entiendes que el catálogo de más de mil conectores es el verdadero argumento del servicio.
Has construido el flujo real de Contoso de principio a fin: petición HTTP con esquema, condición sobre los 60 minutos, consulta parametrizada a db-reservas, llamada a una función para la compensación, bucle sobre los pasajeros con concurrencia limitada, aviso al canal de operaciones e incidente en el sistema de soporte. Y has leído su definición JSON, que es lo que convierte el diseñador en algo versionable en contoso-infra: @triggerBody()?[...] con acceso seguro, runAfter como orden real de ejecución y control explícito del paralelismo. Manejas el control de flujo completo —condiciones, Switch, for each, Until acotado, ámbitos y ramas paralelas— y las tres capas de gestión de errores: directivas de reintento (desactivadas donde la acción no es idempotente), acciones de ejecución posterior como catch, y compensación, porque aquí no hay transacciones. Sabes autenticar con identidad administrada siempre que se pueda y con una cuenta de servicio del dominio cuando toca OAuth delegado, depurar leyendo entradas y salidas reales en el historial y reejecutar, y disparar flujos desde Azure Monitor, Defender for Cloud y Event Grid. Y te llevas dos avisos concretos: el problema de las conexiones al promocionar entre entornos, con su disciplina de parámetros y recursos separados, y el coste por acción, que se dispara con el sondeo cada minuto y los bucles mal colocados.
Queda algo más profundo, y es el sustrato de todo lo anterior. Cada vez que Contoso confirma una reserva, hoy pasan seis cosas en línea, dentro de la misma petición: se cobra, se actualiza la disponibilidad, se emite la tarjeta, se acreditan las millas, se avisa a facturación y se envía la confirmación. Si el servicio de millas está caído, la compra falla. Es una arquitectura acoplada, y ni Functions ni Logic Apps la arreglan por sí solos: hace falta que los componentes dejen de llamarse directamente y empiecen a intercambiar mensajes y eventos. La lección siguiente, Mensajería y eventos: Service Bus, Event Grid y Event Hubs, ataca eso de frente: la distinción entre mensaje y evento que casi todo el mundo confunde, los tres servicios con su tabla decisoria, colas y temas con filtros y cola de mensajes con problemas de entrega, distribución de eventos con CloudEvents, ingesta masiva de telemetría con captura hacia el Data Lake, y el diseño completo del flujo de Contoso con las consecuencias que ya intuyes: entrega al menos una vez, ordenación e idempotencia.
Curso de Azure
Módulo 1: Introducción a Azure
- ¿Qué es Azure?
- Modelos de servicio, regiones y zonas de disponibilidad
- Crear y configurar tu cuenta de Azure
- Recorrido por el portal de Azure
- Azure Resource Manager: suscripciones, grupos de recursos y etiquetas
- Azure CLI, PowerShell y Cloud Shell
Módulo 2: Servicios principales de Azure
- Máquinas virtuales de Azure
- Escalado y alta disponibilidad del cómputo
- Azure App Service
- Azure Storage: blobs, archivos, colas y tablas
- Redes en Azure: redes virtuales, subredes y NSG
- Conectividad híbrida y entrega global
Módulo 3: Bases de datos de Azure
- Elegir el servicio de datos adecuado
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de datos: Data Lake, Data Factory y Synapse
Módulo 4: Seguridad en Azure
- Microsoft Entra ID y gestión de identidades
- RBAC e identidades administradas
- Azure Key Vault
- Protección DDoS y firewall de aplicaciones web
- Microsoft Defender for Cloud
- Gobernanza y cumplimiento con Azure Policy
Módulo 5: Azure DevOps
- Introducción a Azure DevOps
- Azure Repos
- Azure Pipelines: integración continua
- Despliegue continuo con entornos y aprobaciones
- Azure Artifacts
- Infraestructura como código con Bicep
Módulo 6: Servicios avanzados de Azure
- Contenedores en Azure: Container Registry y Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Mensajería y eventos: Service Bus, Event Grid y Event Hubs
- Servicios de IA de Azure
Módulo 7: Monitoreo y gestión
- Azure Monitor: métricas, alertas y paneles
- Log Analytics y consultas KQL
- Application Insights
- Azure Automation y runbooks
- Copias de seguridad y recuperación ante desastres
Módulo 8: Gestión y optimización de costos
- Calculadora de precios y estimación de costes
- Azure Cost Management: análisis, presupuestos y alertas
- Reservas, planes de ahorro y Azure Hybrid Benefit
- Azure Advisor
- Estrategias de optimización y cultura FinOps
