Azure y cloud

Arquitectura serverless para aplicaciones empresariales

Serverless promete pagar solo por uso y olvidar los servidores. En software empresarial también hay que sumar arranques en frío, límites y costos variables.

Por Leyton Manuel Espitia Diaz 5 min de lectura

Fragmento de código C# de una orquestación de Durable Functions con actividades encadenadas

En una presentación, la arquitectura serverless se ve impecable: cada pieza es una función o un servicio administrado, todo escala solo, no hay servidores que parchar y la factura refleja exactamente el uso. En una aplicación empresarial real, con integraciones heredadas, requisitos de auditoría y picos de fin de mes, la imagen tiene más matices.

Serverless no es una arquitectura que se adopta completa o no se adopta. Es un conjunto de servicios que encajan muy bien en algunas partes del sistema y mal en otras.

Qué significa serverless en Azure

No es solo Azure Functions. Es cualquier servicio donde no administras la infraestructura y pagas (total o parcialmente) por uso:

Necesidad Servicio
Código disparado por eventos Azure Functions
Contenedores sin administrar un clúster Azure Container Apps (con escala a cero)
Mensajería Service Bus, Event Grid, Storage Queues
Flujos de integración con conectores Logic Apps
Base de datos que escala y se pausa Azure SQL Database serverless, Cosmos DB serverless
Archivos Blob Storage

Una arquitectura serverless combina estas piezas: los eventos fluyen entre servicios administrados, y el código propio se limita a la lógica de negocio.

Dónde brilla en aplicaciones empresariales

Integraciones y procesamiento por eventos

Proveedor sube un archivo → Blob Storage → Event Grid → Function valida y transforma
                                                         → Service Bus → Function carga en el ERP

Cada paso escala solo, los errores se aíslan y un pico de 5.000 archivos el último día del mes no requiere planificar capacidad.

Flujos largos con Durable Functions

Un proceso de aprobación que espera días, un flujo de alta de clientes con varios pasos y compensaciones, una orquestación de varias llamadas externas:

[Function(nameof(OnboardCustomer))]
public static async Task OnboardCustomer([OrchestrationTrigger] TaskOrchestrationContext context)
{
    var request = context.GetInput<OnboardingRequest>()!;

    await context.CallActivityAsync(nameof(CreateAccount), request);
    await context.CallActivityAsync(nameof(SendContract), request);

    // Espera la firma hasta 7 días sin consumir recursos
    using var cts = new CancellationTokenSource();
    var signed = context.WaitForExternalEvent<bool>("ContractSigned");
    var timeout = context.CreateTimer(context.CurrentUtcDateTime.AddDays(7), cts.Token);

    if (await Task.WhenAny(signed, timeout) == signed)
    {
        cts.Cancel();
        await context.CallActivityAsync(nameof(ActivateAccount), request);
    }
    else
    {
        await context.CallActivityAsync(nameof(CancelOnboarding), request);
    }
}

El estado del flujo se guarda automáticamente. Si el proceso se reinicia, la orquestación continúa donde iba. La condición es respetar sus reglas: el código del orquestador debe ser determinista (nada de DateTime.Now, Guid.NewGuid() ni llamadas de red directas), porque se reejecuta para reconstruir el estado.

Cargas esporádicas o estacionales

Procesos que corren pocas veces al mes, ambientes de prueba que se usan unas horas al día, herramientas internas con poco uso. Pagar por uso es mucho más barato que mantener servidores encendidos.

Dónde se complica

Costos impredecibles

El costo por uso es una ventaja con tráfico bajo y un riesgo con tráfico alto o mal controlado. Un error que reintenta en bucle, un disparador mal configurado o un pico inesperado se convierten en una factura alta. Presupuestos con alertas y límites de escala son parte del diseño, no un detalle posterior.

Arranques en frío y latencia

Los servicios que escalan a cero tardan en responder la primera petición. Para procesos en segundo plano no importa; para una API que atiende usuarios, sí. Los planes con instancias siempre listas lo resuelven, pero con un costo fijo que reduce la ventaja económica (lo vimos en Azure Functions vs API tradicional).

Sistemas heredados y redes privadas

Las aplicaciones empresariales hablan con bases de datos en las oficinas, ERPs internos y servicios detrás de VPN. Conectar servicios serverless a redes privadas es posible (integración con VNet, endpoints privados), pero suele requerir planes específicos y más configuración de la que sugieren los ejemplos.

Dependencia del proveedor

Una arquitectura construida sobre Durable Functions, Event Grid y Logic Apps es difícil de mover a otro proveedor o a infraestructura propia. Para algunas empresas eso es aceptable; para otras, un riesgo que hay que evaluar desde el principio. Mantener la lógica de negocio en bibliotecas normales de .NET, separada de los disparadores, reduce ese acoplamiento.

Observabilidad

Un flujo que atraviesa cinco servicios administrados necesita trazas distribuidas, correlación de mensajes y alertas sobre colas y mensajes muertos. Sin eso, diagnosticar por qué un archivo no llegó al ERP se vuelve una búsqueda manual entre varios portales.

Una combinación que suele funcionar

Usuarios ──► API en App Service o Container Apps (latencia estable)
                    │
                    ▼ eventos
             Service Bus / Event Grid
                    │
       ┌────────────┼─────────────┐
       ▼            ▼             ▼
  Functions     Durable        Logic Apps
 (procesos)   (flujos largos) (integraciones con conectores)

La parte síncrona, que atiende usuarios, en un servicio con capacidad estable. La parte asíncrona, que reacciona a eventos, en serverless.

El trade-off

Serverless cambia administración de infraestructura y capacidad ociosa por costos variables, límites de la plataforma y dependencia del proveedor. Para procesos por eventos, integraciones y cargas esporádicas, el intercambio es muy favorable. Para el núcleo transaccional con tráfico constante, suele no serlo.

Cuándo no usar serverless

  • APIs con tráfico alto y constante, donde el costo por ejecución supera al de capacidad reservada.
  • Procesos que requieren latencia baja garantizada desde la primera petición.
  • Organizaciones que necesitan portabilidad entre proveedores o despliegue en infraestructura propia.
  • Equipos sin experiencia en sistemas distribuidos y sin observabilidad: los problemas serán más difíciles de diagnosticar que en una aplicación tradicional.

Conclusión

Serverless no reemplaza a la arquitectura tradicional en una aplicación empresarial: la complementa. Úsalo donde el trabajo llega por eventos, de forma irregular o en flujos largos, y mantén en servicios con capacidad estable lo que atiende usuarios de forma constante. Con eventos bien diseñados entre las dos partes, cada una hace lo que mejor sabe hacer.

Leyton Manuel Espitia Diaz

Escrito por

Leyton Manuel Espitia Diaz

CEO y fundador de Nakanaba

Desarrollador de software y fundador de Nakanaba. Lidera la arquitectura de Vitrin: backend en .NET, aplicaciones en Angular y .NET MAUI, SQL Server y servicios en Cloudflare.

Lleva tu aplicación a la nube con criterio

Diseñamos arquitecturas en Azure que crecen con tu negocio sin disparar los costos de infraestructura.

Ver soluciones escalables