Nota previa

Este artículo iba a ser “otro post más” sobre Azure IoT… y ha acabado convirtiéndose en un pequeño monográfico. Por eso, esta vez no lo acompaño con un PDF: prefiero que se quede aquí, vivo y en abierto.

Este monográfico complementa el libro de IoT que publiqué hace un tiempo (puedes encontrarlo, junto con el resto de contenidos, en este mismo blog) y cierra un círculo que me parecía necesario:

  • explicar qué es realmente Azure IoT Operations,

  • cómo se relaciona con Microsoft Fabric desde el punto de vista del dato,

  • y por qué tenía sentido hablar de ambos juntos en el mismo hilo.

Si después de leerlo entiendes mejor:

  • dónde encaja IoT Operations en tu arquitectura industrial,

  • qué papel juega Fabric en la cadena de valor del dato,

  • y cuándo tiene sentido ir más allá de IoT Hub + IoT Edge,

entonces este monográfico habrá cumplido su propósito.

Introducción

Azure IoT Operations es la plataforma de IoT industrial que extiende la nube adaptativa de Microsoft hasta el perímetro (edge). Está habilitada por Azure Arc e integra servicios de datos modulares en clústeres Kubernetes perimetrales. A diferencia de un enfoque 100% en la nube, Azure IoT Operations permite procesar y normalizar datos in situ (en el edge) antes de enviarlos a Azure, facilitando casos de uso de mantenimiento predictivo, optimización de procesos y seguridad operacional en entornos industriales.
En este artículo técnico abordaremos tres aspectos clave para desarrolladores y tomadores de decisiones:

  1. Guía paso a paso: un ejemplo de despliegue de Azure IoT Operations usando una máquina virtual como dispositivo perimetral (Edge). Cubriremos la instalación de componentes necesarios, configuración de red, conexión con Azure y verificación del funcionamiento.
  2. Comparativa técnica: diferencias entre Azure IoT Operations, Azure IoT Hub y Azure IoT Edge (incluyendo consideraciones sobre procesamiento de señales DSP en el perímetro). Analizaremos arquitectura, casos de uso, facilidad de integración y capacidades en entornos industriales.
  3. Caso de uso en manufactura: un escenario hipotético de una planta industrial que se beneficia de Azure IoT Operations para mejorar eficiencia, mantenimiento predictivo y seguridad operativa.

¿Qué es Azure IoT Operations y cómo se diferencia de IoT Hub?

Azure IoT Operations: El Edge Industrial Inteligente

Azure IoT Operations es una plataforma edge-native diseñada específicamente para entornos industriales (OT – Operational Technology). Se ejecuta en clústeres Kubernetes en el perímetro y proporciona:

 

  • Broker MQTT de grado industrial: Capaz de manejar millones de mensajes por día con baja latencia
  • Conectividad nativa OPC UA: Descubrimiento automático de activos industriales con Akri
  • Procesamiento local de datos: Transformación, filtrado y contextualización antes de enviar a la nube
  • Resiliencia offline: Hasta 72 horas de operación sin conexión a Azure
  • Gestión unificada: Integración con Azure Arc para administrar desde Azure Portal

Azure IoT Hub: El Hub de Mensajería Cloud

Azure IoT Hub es un servicio 100% cloud que actúa como punto central de comunicación bidireccional entre aplicaciones cloud y dispositivos IoT:

 

  • Conectividad masiva: Soporta millones de dispositivos conectados simultáneamente
  • Protocolos estándar: MQTT, AMQP, HTTPS
  • Device Twins: Sincronización de estado entre dispositivo y nube
  • Enrutamiento de mensajes: Integración con servicios Azure (Event Hubs, Storage, etc.)
  • Gestión de dispositivos: Provisionamiento, actualización OTA, comandos cloud-to-device

La Diferencia Clave: ¿Dónde viven tus datos?

IoT Hub (por sí solo) asume que tus dispositivos envían todos los datos a la nube y el procesamiento ocurre allí. Sin embargo, cuando se combina con IoT Edge, también permite procesamiento en el perímetro. La diferencia está en la escala:

 

IoT Hub + IoT Edge es ideal para:
  • Procesamiento ligero en el perímetro (filtrado, agregación básica)
  • Decenas o cientos de dispositivos por gateway
  • Transformaciones simples antes de enviar a la nube
  • Volúmenes moderados (cientos de miles de mensajes por día)

IoT Operations está diseñado específicamente para procesamiento pesado en el edge:

  • Plantas industriales con miles de sensores generando datos cada milisegundo
  • Millones de mensajes por día procesados localmente
  • Entornos con conectividad inestable o limitada
  • Requisitos de latencia ultra-baja (< 10ms)
  • Procesamiento complejo: ML, agregaciones, transformaciones, DSP
  • Alta disponibilidad y resiliencia (clústeres Kubernetes multi-nodo)
  • Regulaciones que impiden enviar ciertos datos fuera de las instalaciones

En resumen: IoT Edge es para cargas ligeras, IoT Operations es para cargas industriales pesadas.

Ejemplo de despliegue paso a paso con un dispositivo Edge

Preparar la máquina virtual y el entorno Kubernetes

Seleccionamos una VM con recursos suficientes para actuar como nodo perimetral. Por ejemplo, la configuración mínima recomendada por Microsoft es:
  •  VM: Standard_D4ds_v5 (4 vCPU, 16 GB RAM)
  • SO: Ubuntu 22.04 LTS
  • Kubernetes: K3s de un nodo (ligero y optimizado para edge)

Instalamos el runtime Kubernetes y herramientas necesarias:

# Instalar K3s
curl -sfL https://get.k3s.io | sh -

# Verificar instalación
sudo kubectl get nodes

# Instalar Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Instalar herramientas adicionales
sudo apt-get install -y helm jq
Conectividad de redLa VM debe tener:
  • Acceso a internet para comunicarse con Azure Arc
  • Acceso a la red local de dispositivos industriales (OPC UA, Modbus, etc.)
  • Apertura de puertos según requisitos de red

Conectar el clúster perimetral a Azure Arc

Una vez operativo el clúster Kubernetes, habilitamos Azure Arc para administrarlo desde Azure:
# Iniciar sesión en Azure
az login

# Registrar proveedores necesarios
az provider register --namespace Microsoft.Kubernetes
az provider register --namespace Microsoft.ExtendedLocation
az provider register --namespace Microsoft.IoTOperations
az provider register --namespace Microsoft.DeviceRegistry

# Conectar clúster a Azure Arc
az connectedk8s connect \
  --name iotops-aks \
  --resource-group iotops-rg \
  --location eastus \
  --enable-oidc-issuer \
  --enable-workload-identity \
  --disable-auto-upgrade
Este comando registra el clúster local en Azure Arc, vinculándolo como recurso de Azure. Se habilitan:
  • OIDC Issuer: Para autenticación federada
  • Workload Identity: Para que los pods accedan a servicios Azure sin credenciales hardcodeadas

Más información: Conectar un clúster Kubernetes a Azure Arc

    Instalar la extensión de IoT Operations

    # Instalar extensión CLI
    az extension add --upgrade --name azure-iot-ops
    
    # Crear namespace para Device Registry
    az iot ops ns create \
      --name iotops-ns \
      --resource-group iotops-rg
    
    # Crear Schema Registry
    az iot ops schema registry create \
      --name iotops-schema \
      --resource-group iotops-rg \
      --registry-namespace iotopsns \
      --sa-resource-id <STORAGE_ACCOUNT_ID>
    Documentación oficial: Implementar Azure IoT Operations

    Desplegar Azure IoT Operations en el clúster

    # Inicializar el clúster para IoT Operations
    az iot ops init \
      --cluster iotops-aks \
      --resource-group iotops-rg
    
    # Crear instancia de IoT Operations (modo prueba)
    az iot ops create \
      --cluster iotops-aks \
      --resource-group iotops-rg \
      --name iotops-aks-instance \
      --sr-resource-id <SCHEMA_REGISTRY_ID> \
      --ns-resource-id <NAMESPACE_ID> \
      --broker-frontend-replicas 1 \
      --broker-frontend-workers 1 \
      --broker-backend-part 1 \
      --broker-backend-workers 1 \
      --broker-backend-rf 2 \
      --broker-mem-profile Low
    La instalación despliega múltiples componentes:
    • MQTT Broker: Servicio de mensajería industrial
    • OPC UA Connector: Para descubrir y conectar dispositivos OPC UA
    • Data Processor: Motor de transformación y enrutamiento
    • Device Registry: Registro de activos industriales

    Configurar conexiones de datos y verificar funcionamiento

    Con Azure IoT Operations desplegado, configuramos la conexión con dispositivos:
    # Simular dispositivo OPC UA
    kubectl run opcplc-server \
      --image=mcr.microsoft.com/iotedge/opc-plc:latest \
      --port=50000 \
      -n azure-iot-operations
    
    # Verificar salud del sistema
    az iot ops check
    Configurar flujo de datos hacia Azure Event Hubs: Más información de como configurar dataflows
    # Monitorear logs del broker MQTT
    kubectl logs -n azure-iot-operations -l app=aio-broker-frontend --tail=50

    Script de despliegue automatizado

    He creado un script completo que automatiza todo el proceso anterior. Puedes encontrarlo en el archivo `deploy_iotops.sh` de este repositorio.

    El script incluye:
    • Creación de recursos Azure (Resource Group, AKS, Storage)
    • Conexión del clúster a Azure Arc
    • Instalación de Azure IoT Operations
    • Configuración de broker MQTT con LoadBalancer
    • Despliegue de VM IoT Edge con cliente Mosquitto
    • Certificados X509 para autenticación (opcional)
    chmod +x deploy_iotops.sh
    ./deploy_iotops.sh

    Una vez que tengas todo desplegado, podrás conectarte a la VM, lanzar un mensaje [1], recibirlo [2] y observarlo desde tu conexión a K8s.

    Llegados a este punto, ya tienes una instancia funcional de Azure IoT Operations desplegada y conectada a Azure Arc, así que podrías pasar perfectamente a la experiencia gráfica:

    Desde aquí puedes abrir el portal de Azure IoT Operations (Operations Experience) y empezar a trabajar de forma visual.

    En ese portal (experience web UI) podrías, por ejemplo:

    Algo así como un “SCADA lógico” sobre tus recursos de IoT Operations: ves el perímetro, los activos, los flujos y su estado casi en tiempo real.

    Sin embargo, en este artículo no me voy a quedar en el “pinta y colorea” del portal. Aunque es muy útil para OT y para el día a día, si solo usamos la UI nunca terminamos de entender bien:

    • Qué CRDs se crean realmente en Kubernetes.

    • Cómo se modelan dispositivos y assets en el Device Registry.

    • Cómo se conectan el broker MQTT, los dataflows y los conectores industriales (OPC UA, Akri, etc.).

    Por eso, voy a seguir con la CLI, los manifiestos YAML y el enfoque GitOps: porque es ahí donde se ve de verdad que Azure IoT Operations no es “otro portal más”, sino un plano de datos industrial sobre Kubernetes, completamente declarativo y gobernable.

    Comparativa: Azure IoT Operations vs Azure IoT Hub vs Azure IoT Edge

    Tabla comparativa técnica

    Criterio Azure IoT Operations Azure IoT Hub Azure IoT Edge
    Modelo de despliegue On-premise en Kubernetes con Azure Arc 100% cloud, Hub central de mensajería Runtime ligero en dispositivos individuales
    Procesamiento en el perímetro Broker MQTT industrial + flujos de datos locales No procesa datos, solo enruta a servicios Azure Módulos personalizados (ML, Stream Analytics, filtros)
    Capacidad de mensajes Millones de mensajes/día por clúster Millones de mensajes/día (con throttling) Limitado por hardware del dispositivo
    Conectividad y protocolos OPC UA nativo, MQTT 5.0, Akri, Event Hubs/Grid MQTT 3.1.1, AMQP, HTTPS Gateway para protocolos industriales
    Administración Azure Arc (Device Registry como recurso) Portal IoT Hub, CLI, SDK Gestionado desde IoT Hub
    Escalabilidad Multi-nodo Kubernetes, alta disponibilidad Escalabilidad cloud nativa Limitada por dispositivo edge
    Requisitos mínimos 4 vCPU, 16 GB RAM (recomendado 32 GB) N/A (cloud) 1 vCPU, 512 MB RAM (mínimo)
    Resiliencia offline Hasta 72 horas (configurable) Requiere conexión constante Indefinida
    Latencia típica < 10ms (procesamiento local) 100–500ms (round-trip cloud) < 50ms (procesamiento local)
    Coste Por recursos de clúster + tráfico Azure Por mensajes + device twins + operaciones Por dispositivo + módulos + tráfico

    Casos de uso detallados

    Mejor con Azure IoT Operations

    Planta industrial con miles de activos OPC UA
    • Volumen: 1000 máquinas × 100 señales × 10 Hz = 1 millón de mensajes/seg
    • Problema con IoT Hub: Throttling masivo. IoT Hub S3 (tier más alto) soporta máximo 6000 msg/seg para envío device-to-cloud
    • Solución IoT Operations: Procesamiento local con agregación. Ejemplo: de 1M mensajes/seg se reduce a 10K/seg enviados a la nube (solo alertas y KPIs)
    • Coste: IoT Hub S3 cuesta ~$2500/mes + $0.08 por cada 1M mensajes adicionales. Con IoT Operations pagas el clúster (~$500-1000/mes AKS) + tráfico reducido
    Requisitos de latencia ultra-baja (<10ms)
    • Ejemplo: Sistema de control de calidad visual que debe rechazar piezas defectuosas en tiempo real
    • IoT Hub: Round-trip a cloud = 100-500ms (inviable)
    • IoT Operations: Procesamiento local con ML en edge = <10ms
    Entornos con conectividad intermitente
    • Ejemplo: Mina subterránea, plataforma offshore, fábrica en zona rural
    • IoT Hub: Pérdida de datos durante desconexiones
    • IoT Operations: Buffer local de hasta 72 horas + sincronización automática

    Mejor con Azure IoT Hub

    Flota de sensores IoT simple (cientos de dispositivos)
    • Ejemplo: 500 sensores de temperatura/humedad enviando datos cada minuto
    • Volumen: 500 × 1/60 Hz = 8.3 msg/seg
    • IoT Hub: Perfecto. IoT Hub S1 ($25/mes) soporta hasta 400K mensajes/día
    • IoT Operations: Sobredimensionado (matar moscas a cañonazos)
    Prototipo rápido de solución IoT
    • Sin infraestructura Kubernetes
    • Sin personal con conocimientos de DevOps
    • Time-to-market rápido
    Dispositivos móviles o distribuidos geográficamente
    • Ejemplo: Flota de camiones con telemetría GPS + sensores
    • IoT Hub: Ideal para conectividad global con roaming
    • IoT Operations: No aplica (requiere infraestructura edge fija)

    Complementarios: IoT Operations + IoT Hub

    Arquitectura híbrida recomendada para grandes instalaciones:

    Flujo de datos:
    1. IoT Operations captura millones de señales localmente
    2. Procesa, filtra y agrega en el edge (reduce volumen 100:1)
    3. Envía datos contextualizados a IoT Hub vía MQTT o Event Hubs
    4. IoT Hub orquesta la distribución a servicios Azure (Stream Analytics, Data Lake, etc.)

    Análisis de límites: ¿Cuándo IoT Hub se queda corto?

     

    Límites de IoT Hub (tier S3 – el más alto)

    Métrica Límite S3 Coste
    Mensajes device-to-cloud 6000 msg/seg $2500/mes base
    Operaciones de registro 100 req/seg Incluido
    Trabajos de dispositivos 10 trabajos/seg Incluido
    Device twins updates 500 actualizaciones/seg $0.001 por operación
    A fecha de publicación del artículo: Cuotas y limitación de IoT Hub + Precios.

    Escenario de saturación

    Fábrica con 500 máquinas CNC, cada una con:
    • 50 sensores (temperatura, vibración, posición, velocidad, etc.)
    • Muestreo a 10 Hz (10 lecturas/segundo)
    Cálculo:
    • 500 máquinas × 50 sensores × 10 Hz = 250,000 mensajes/segundo
    Problema con IoT Hub:
    • S3 soporta máximo 6,000 msg/seg
    • Necesitarías 42 instancias de IoT Hub S3 = $105,000/mes
    • Además: throttling, gestión multi-hub, latencia
    Solución con IoT Operations:
    1. Clúster edge (3 nodos, 32 GB RAM cada uno) = $1,500/mes
    2. Procesamiento local: agrega datos a 1 Hz y calcula FFT de vibración
    3. Reduce a 5,000 msg/seg enviados a la nube (solo KPIs + alertas)
    4. IoT Hub S2 ($250/mes) + Event Hubs Standard ($200/mes) = $450/mes
    5. Total: $1,950/mes (ahorro del 98%)

    Límites de latencia

    Arquitectura Latencia típica Caso de uso
    IoT Hub directo 100-500ms Telemetría no crítica
    IoT Edge + IoT Hub 50-200ms Filtrado + telemetría
    IoT Operations local <10ms Control en tiempo real
    IoT Operations + Event Hubs <50ms Streaming analytics

    A fecha de publicación del artículo: Consideraciones de rendimiento IoT Hub

    Caso de uso: Planta manufacturera inteligente con Azure IoT Operations

    Escenario

    Una fábrica automotriz opera más de 500 máquinas en sus líneas de producción:
    • Robots de soldadura
    • Prensas hidráulicas
    • Cintas transportadoras
    • Centros de mecanizado CNC
    • Hornos de curado
    Desafíos:
    1. Datos encerrados en PLCs aislados (silos de información)
    2. Paros no planificados que cuestan $50,000/hora
    3. Conectividad inestable en planta (no 100% confiable)
    4. Requisitos de compliance: datos OT no pueden salir de planta sin procesamiento

    Solución con Azure IoT Operations

    Arquitectura desplegada

    Caso de uso 1: Mantenimiento predictivo de robots de soldadura

    Implementación:
    # DataFlow para monitoreo de vibración
    apiVersion: connectivity.iotoperations.azure.com/v1beta1
    kind: DataFlow
    metadata:
      name: predictive-maintenance-robots
    spec:
      source:
        topic: "opc-ua/robots/+/vibration"
        qos: 1
      transformation:
        - type: enrichment
          contextQuery: "SELECT deviceId, location FROM assets"
        - type: filter
          expression: "vibration > 0.5 OR temperature > 80"
        - type: aggregate
          window: "5s"
          functions:
            - name: rms
              field: vibration
            - name: avg
              field: temperature
      destination:
        endpoint: "eventhub-alerts"
        topic: "anomalies/robots"

    Como podeis observar aquí es donde empieza la mágia de IoT Operations, hasta ahora solo pensabamos en un K8s; a partir de ahora ya debes pensar en un conjunto de integraciones. Aunque es cierto que justamente esta parte de los YAML esta en preview.

    Resultados medibles:

    • 3 robots salvados de fallo crítico en 6 meses
    • Ahorro: $150,000 en reparaciones + tiempo de línea
    • Reducción del 40% en mantenimientos reactivos
    • Aumento del MTBF (Mean Time Between Failures) de 45 a 68 días

    Caso de uso 2: Monitoreo de eficiencia (OEE)

    Métricas calculadas en edge:
    // Ejemplo de cálculo OEE local
    const availability = actualRunTime / plannedProductionTime;
    const performance = (idealCycleTime × totalPieces) / actualRunTime;
    const quality = goodPieces / totalPieces;
    const oee = availability × performance × quality;
    
    // Publicar solo KPIs agregados (no señales raw)
    publish('azure/kpi/oee', {
      line: 'assembly-1',
      oee: oee,
      timestamp: Date.now(),
      breakdown: { availability, performance, quality }
    });
    Resultados:
    • OEE global aumentó de 68% a 73% (+7.4%)
    • Identificadas 12 micro-paradas no documentadas
    • Cuello de botella resuelto en Estación 5 → +15% throughput

    Documentación: Calcular OEE con Azure IoT

    Caso de uso 3: Seguridad operativa

    Sistema de alertas en tiempo real:
    # Configurar alerta de sobrecalentamiento
    apiVersion: connectivity.iotoperations.azure.com/v1beta1
    kind: DataFlow
    metadata:
      name: safety-temperature-alert
    spec:
      source:
        topic: "sensors/temperature/+/oven"
      transformation:
        - type: filter
          expression: "temperature > 850"  # Límite crítico
      destination:
        endpoint: "event-grid-alerts"
        topic: "safety/critical/temperature"
    Integración con Logic App:
    {
      "trigger": {
        "type": "EventGrid",
        "inputs": {
          "topic": "safety/critical/temperature"
        }
      },
      "actions": {
        "SendSMS": {
          "type": "Twilio",
          "inputs": {
            "to": "${supervisor.phone}",
            "message": "ALERTA: Horno #${deviceId} a ${temperature}°C"
          }
        },
        "TriggerSafety": {
          "type": "HTTP",
          "inputs": {
            "method": "POST",
            "uri": "https://plc-gateway/api/emergency-stop",
            "body": { "deviceId": "${deviceId}" }
          }
        }
      }
    }
    Incidente real evitado:
    • Sensor detectó sobrecalentamiento en horno a 920°C (límite: 850°C)
    • Alerta en <5 segundos → supervisor notificado
    • Sistema activó extractores automáticamente
    • Incendio potencial evitado → Ahorro: incalculable

    Más información: Integrar con Azure Event Grid

    Beneficios cuantificados

    Métrica Antes Después Mejora
    MTBF robots 45 días 68 días +51%
    OEE global 68% 73% +7.4%
    Paros no planificados 12/mes 3/mes -75%
    Coste de mantenimiento $80K/mes $52K/mes -35%
    Incidentes de seguridad 4/año 0/año -100%
    Coste IT/OT $8K/mes (múltiples sistemas) $2K/mes (IoT Ops unificado) -75%

    ¿IoT Edge o IoT Operations? No es una competencia, es una evolución

    En mi experiencia trabajando con equipos OT/IT en fábricas reales, muchos proyectos con IoT Edge “puro” acabaron tropezando siempre en los mismos puntos: coste operativo, límite de hardware y complejidad de escalar cuando pasas de 10 a 300 dispositivos. No es que IoT Edge sea malo: es brillante para gateways dedicados, módulos específicos o escenarios offline. Pero la realidad es que mantener decenas o cientos de Edge Boxes con módulos personalizados se vuelve inviable si la organización no está preparada para operar esa complejidad. He visto líneas donde los edges se saturaban por intentar correr análisis que nunca debieron ejecutarse en un dispositivo ARM con 4 GB de RAM. He visto plantas donde se perdían mensajes porque cada módulo era “artesanal” y nadie tenía control del backpressure. Y he visto proyectos que se frenaron simplemente porque “necesitábamos otro Edge más, pero el hardware ya no daba”.

    Por eso digo siempre que IoT Operations no compite con IoT Edge: lo trasciende. Es el paso natural cuando la planta ya aprendió los límites del modelo anterior. Pasas de 100 cajitas con Linux a una plataforma industrial unificada sobre Kubernetes, donde cada flujo se gobierna, cada recurso se escala y cada mensaje se enruta con mecanismos diseñados para miles de eventos por segundo. No es “usar más cloud”: es eliminar el bricolaje OT y sustituirlo por una plataforma declarativa, auditable y preparada para cargas industriales. En otras palabras: IoT Edge te lleva a empezar. IoT Operations te permite sobrevivir cuando la planta despega.

    La relación entre hermanos

    En el ecosistema de soluciones industriales conectadas, Azure IoT Edge y Azure IoT Operations no compiten: se complementan.

    Podríamos decir que IoT Edge es el hermano menor de IoT Operations.

    Azure IoT Edge: El hermano táctico

    • Ligero: Corre en Raspberry Pi (512 MB RAM mínimo)
    • Modular: Contenedores individuales con funciones específicas
    • Embebido: Perfecto para gateways industriales compactos
    • Offline-first: Opera indefinidamente sin conexión cloud
    • Maduro: Desde 2017, battle-tested, feature-complete

    Casos ideales:

    • Sitios remotos con 10-100 dispositivos
    • Conectividad intermitente prolongada
    • Hardware limitado (ARM, bajo consumo)
    • Conversión de protocolos (Modbus → MQTT → IoT Hub)

    Azure IoT Operations: El hermano estratégico

    • Industrial-grade: Kubernetes multi-nodo con HA
    • Escalable: Miles de activos, millones de mensajes/día
    • Integrado: OPC UA nativo, Azure Arc, Event Hubs
    • Resiliente: Failover automático, almacenamiento persistente
    • Moderno: MQTT 5.0, cloud-native, GitOps-ready
    Casos ideales:
    • Plantas industriales con 500+ máquinas
    • Requisitos de alta disponibilidad (99.9% SLA)
    • Procesamiento complejo en edge (ML, DSP, agregaciones)
    • Gestión centralizada de múltiples sitios

    Matriz de decisión

    Criterio IoT Edge IoT Operations
    Número de dispositivos 10–1,000 1,000–100,000+
    Mensajes/día Miles–Millones Millones–Miles de millones
    Hardware mínimo 1 vCPU, 512 MB 4 vCPU, 16 GB
    Coste mensual $50–500 $500–5,000+
    Time-to-market Días Semanas
    Complejidad operativa Baja Media–Alta
    Máximo escalamiento 1 dispositivo Clúster multi-nodo
    Offline resilience Indefinida 72h (configurable)

    Migración natural: De Edge a Operations

    La buena noticia: Ambas plataformas usan contenedores, así que tu inversión en IoT Edge no se pierde. Ejemplo de migración:
    # Módulo IoT Edge (módulo de análisis de vibración)
    # deployment.json
    {
      "modulesContent": {
        "$edgeAgent": {
          "properties.desired": {
            "modules": {
              "vibration-analysis": {
                "settings": {
                  "image": "myregistry.azurecr.io/vibration-analysis:1.0"
                }
              }
            }
          }
        }
      }
    }
    
    # Mismo módulo en IoT Operations (Kubernetes deployment)
    # vibration-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vibration-analysis
    spec:
      replicas: 3  # ← Ahora con HA!
      selector:
        matchLabels:
          app: vibration-analysis
      template:
        spec:
          containers:
          - name: vibration-analysis
            image: myregistry.azurecr.io/vibration-analysis:1.0
            # ← Mismo contenedor, mayor escala
    Lo que cambia:
    • Orquestación (IoT Edge Hub → Kubernetes)
    • Escala (1 dispositivo → N nodos)
    • Gestión (Azure Portal → Azure Arc)
    Lo que no cambia:
    • El código de tu aplicación
    • Las imágenes de contenedor

    Cuándo saltar de Edge a Operations?

    Señales de que necesitas evolucionar:

     

    • Saturación de hardware
      • Tu dispositivo Edge está al 80%+ CPU constante
      • Necesitas más de 1 dispositivo Edge en el mismo sitio
    • Requisitos de HA
      • Un fallo de hardware detiene tu operación
      • Necesitas SLA de 99.9% o superior
    • Complejidad de gestión
      •  Más de 10 dispositivos Edge para mantener
      •  Múltiples sitios con configuraciones similares
    • Volumen de datos
      • Más de 100K mensajes/segundo por sitio
      • Necesitas agregación/procesamiento complejo
    • Integración OT-IT
      • Múltiples protocolos industriales (OPC UA, Modbus, EtherNet/IP)
      • Requisitos de Device Registry centralizado
    Regla de oro:
    • Decenas de dispositivos → IoT Edge
    • Cientos de dispositivos → Evalúa ambos
    • Miles de dispositivos → IoT Operations

    Complementariedad: El poder de la arquitectura híbrida

    Flujo de datos unificado:
    1. Planta Central: IoT Operations procesa localmente, envía KPIs agregados
    2. Plantas Regionales: IoT Edge filtra y almacena, envía a IoT Hub
    3. IoT Hub: Orquesta gestión de dispositivos Edge + recibe telemetría
    4. Event Hubs: Recibe eventos de alta frecuencia de IoT Operations
    5. Microsoft Fabric: Consolida datos de todas las fuentes
    Beneficios de esta arquitectura:
    • Coste optimizado: Edge para sitios pequeños, Operations para grandes
    • Gestión unificada: Todo visible en Azure Arc
    • Resiliencia: Cada sitio opera independientemente
    • Escalabilidad: Añade sitios sin rehacer arquitectura

    Conclusiones: Eligiendo la solución correcta

    Para desarrolladores

    Empieza con IoT Hub + IoT Edge si:
    • Necesitas un prototipo rápido (<1 semana)
    • Presupuesto limitado (<$1,000/mes)
    • Equipo pequeño sin experiencia Kubernetes
    • Volumen moderado (<1M mensajes/día)
    Evoluciona a IoT Operations cuando:
    • Escalar a múltiples plantas industriales
    • Volumen crítico (>10M mensajes/día)
    • Requisitos de compliance OT estrictos
    • SLA de 99.9%+ requerido

    Para CTOs y tomadores de decisiones

    Inversión recomendada:
    Fase 1: Proof of Concept (3 meses)
    → IoT Hub + IoT Edge
    → Inversión: $5-10K
    → Objetivo: Validar valor de negocio
    Fase 2: Piloto en 1 planta (6 meses)
    → IoT Operations en producción
    → Inversión: $50-100K
    → Objetivo: Métricas de ROI reales
    Fase 3: Rollout enterprise (12-24 meses)
    → IoT Ops (plantas grandes) + IoT Edge (sitios remotos)
    → Inversión: $500K-2M
    → Objetivo: Transformación digital completa
    ROI esperado:
    • 15-25% reducción en costes operativos
    • 10-20% aumento en productividad (OEE)
    • 30-50% reducción en mantenimiento reactivo
    • 60-80% reducción en incidentes de seguridad

    Seguridad en Azure IoT Operations: el perímetro como plano zero-trust

    Hasta ahora hemos hablado de arquitectura, flujos y casos de uso. Pero cuando llevamos Kubernetes al perímetro industrial, la conversación de seguridad deja de ser un “extra” para convertirse en un pilar estructural. Azure IoT Operations no es un broker MQTT “con esteroides”, es una plataforma industrial que opera en uno de los entornos más exigentes en seguridad: las redes OT.

    Por eso, la propia arquitectura incorpora mecanismos de defensa integrados en varios planos:

    Malla de Identidad: OIDC + Workload Identity

    Desde que conectamos el clúster a Azure Arc, dejamos claro que no queremos ni un solo secreto estático dentro de los pods.
    La autenticación entre workloads y servicios Azure se hace mediante:

    • OIDC Issuer del clúster (firmado por Arc)

    • Microsoft Entra Workload Identity

    • Token exchange automático sin credenciales en disco

    ¿Consecuencia?

    Cada pod obtiene identidades efímeras y verificables. Nada de cadenas de conexión, nada de claves en ConfigMaps, nada de secretos rotos en un commit.

    Aislamiento de flujos OT–IT

    Azure IoT Operations separa explícitamente los planos:

    • Plano de datos OT (OPC UA, MQTT 5.0, Akri, conectores)

    • Plano de control (CRDs, DataFlows, Device Registry)

    • Plano de gestión Azure Arc

    Esto evita que un compromiso en OT impacte la administración cloud, y viceversa.

    Seguridad de mensajería industrial

    El broker MQTT soporta:

    • Autenticación X.509

    • Mutual TLS

    • Encriptación in-flight

    • ACLs declarativas para topic-level security

    • QoS y backpressure para evitar DoS internos

    Esto no es trivial: en fábricas reales, muchas brechas han venido de sensores inseguros, dispositivos sin patch y redes horizontales. IoT Operations introduce una capa de seguridad que antes simplemente no existía.

    Escaneo y firma de contenedores

    Porque todo corre sobre Kubernetes, podemos integrar:

    • Microsoft Defender for Containers

    • Microsoft Artifact Security

    • Firma Notary / cosign

    • Políticas Kyverno / Gatekeeper

    Ejemplo de política:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: require-signed-images
    spec:
      validationFailureAction: enforce
      rules:
      - name: only-signed-images
        match:
          resources:
            kinds:
            - Pod
        verifyImages:
        - image: "*"
          key: "cosign.pub"

    Con esto te aseguras de que ningún pod industrial se despliega si la imagen no está firmada.

    Local-first security en entornos hostiles

    Como IoT Operations opera en sitios offline o con red inestable, incorpora:

    • Persistencia local

    • Reintento automático

    • Validación de identidad en edge

    • Cifrado en reposo opcional con CSI drivers

    • Rotación de claves gestionada por Arc

    En otras palabras: el clúster sigue siendo seguro aunque pierda la conexión con Azure durante 72 horas o más.

    Gobernanza en Azure IoT Operations: del bricolaje OT a la operación declarativa

    Cuando una planta industrial pasa de 20 gateways IoT Edge a cientos de máquinas conectadas, el problema deja de ser técnico y pasa a ser gobernanza. ¿Quién gestiona los dataflows? ¿Quién puede publicar topologías? ¿Cómo se controla el cambio?

    Azure IoT Operations introduce un marco de gobernanza al estilo cloud-native pero aplicado al OT:

    CRDs: todo es declarativo

    Cada componente del sistema es un recurso Kubernetes:

    • DataFlows

    • Endpoints

    • Assets (Device Registry)

    • Pipelines de transformación

    • Conectores industriales

    El ciclo operativo ya no depende de “abrir un Edge y cambiar una config”, sino de manifest YAML versionados en Git.

    GitOps como requisito (no como recomendación)

    Este es uno de los grandes aciertos del diseño:

    • Las plantas ya no se gestionan por SSH

    • No hay “configuración viviente” que se pierde

    • Puedes recrear un site completo desde Git

    Dejas de tener “cien cajitas con su propia vida” y pasas a una plataforma reproducible, coherente y protegida por PRs, revisiones y auditoría centralizada.

    Governance aplicada al OT: RBAC para operar fábricas

    Con Azure Arc + Kubernetes RBAC puedes definir roles como los de una organización real:

    • OT Engineer: Puede crear DataFlows, revisar logs, ajustar conectores.

    • IT/DevOps: Administra clúster, políticas, identidad y CI/CD.

    • Supervisor de planta: Solo observa métricas y estado (lectura).

    • Proveedor externo: Acceso temporal controlado a un namespace aislado.

    Esto simplemente no existía con IoT Edge tradicional: cada dispositivo era un silo independiente.

    Auditoría centralizada y trazabilidad

    Cada cambio en IoT Operations queda registrado:

    • Git (origen de la verdad)

    • Arc (operaciones y actualizaciones)

    • Kubernetes (eventos y cambios en CRDs)

    • Defender (alertas de seguridad)

    Esto permite cumplir fácilmente con normativas industriales IEC 62443, NIST 800-82, etc.

    Azure API Management en el clúster: el puente gobernado entre OT y servicios IT/Cloud

    Esta pieza encaja perfectamente en IoT Operations, porque no todas las plantas quieren (ni deben) exponer MQTT o OPC UA directamente a servicios externos.

    API Management en modo self-hosted gateway dentro del clúster ofrece:

    Control de superficie de ataque

    • Terminas TLS en APIM

    • Expone solo APIs gobernadas

    • Ocultas el broker MQTT y conectores internos

    • Evitas conexiones directas a workloads OT

    Políticas de seguridad centralizadas

    Puedes aplicar:

    • Validación de JWT

    • Throttling

    • Rate limiting por planta

    • IP filtering

    • Transformaciones de payload

    Ejemplo de política:

    <inbound>
        <validate-jwt header-name="Authorization"
                      failed-validation-httpcode="401"
                      output-token-variable-name="jwt">
            <openid-config url="https://login.microsoftonline.com/.../v2.0/.well-known/openid-configuration" />
            <required-claims>
                <claim name="roles">
                    <value>iotops.operator</value>
                </claim>
            </required-claims>
        </validate-jwt>
        <rate-limit-by-key calls="1000" renewal-period="60" counter-key="@(context.Subscription.Id)" />
    </inbound>

    Unificación de entrada/salida

    APIM puede exponer:

    • APIs REST para consultar assets

    • KPIs procesados por los DataFlows

    • Acceso seguro a Event Hubs / Fabric

    • Webhooks para Logic Apps o Functions

    • Entrada de comandos IT → OT gobernados

    Esto convierte IoT Operations en una plataforma industrial con contratos de API estables, sin exponer la estructura interna del clúster.

    Microsoft Fabric: El paso natural para visualizar y analizar datos IoT

    ¿Por qué Microsoft Fabric con IoT Operations?

    Microsoft Fabric es la plataforma de análisis unificada de Microsoft que integra capacidades de ingesta de datos, almacenamiento, procesamiento y visualización en un solo lugar. Es el complemento perfecto para Azure IoT Operations porque:

    1. Ingesta nativa desde Event Hubs: Los datos que IoT Operations envía a Event Hubs fluyen automáticamente a Fabric
    2. Real-Time Intelligence: Análisis de streaming en tiempo real con KQL (Kusto Query Language)
    3. OneLake: Donde convergen todos los datos IoT
    4. Power BI integrado: Dashboards interactivos sin necesidad de exportar datos
    5. Democratización de datos: Equipos OT y TI acceden a la misma información

    Arquitectura: Del Edge a Fabric

      Casos de uso: Del dato a la acción

      Dashboard OEE en tiempo real

      Flujo de datos:
      Query KQL para calcular OEE:
      // Calcular OEE en ventanas de 5 minutos
      MachineMetrics
      | where timestamp > ago(1h)
      | summarize 
          TotalRunTime = sum(runtime_seconds),
          PlannedProductionTime = sum(planned_seconds),
          TotalPieces = sum(pieces_produced),
          GoodPieces = sum(good_pieces),
          IdealCycleTime = avg(ideal_cycle_time)
          by bin(timestamp, 5m), machine_id, line
      | extend 
          Availability = TotalRunTime / PlannedProductionTime,
          Performance = (IdealCycleTime * TotalPieces) / TotalRunTime,
          Quality = toreal(GoodPieces) / TotalPieces,
          OEE = (TotalRunTime / PlannedProductionTime) * 
                ((IdealCycleTime * TotalPieces) / TotalRunTime) * 
                (toreal(GoodPieces) / TotalPieces)
      | project timestamp, machine_id, line, 
                OEE = round(OEE * 100, 2),
                Availability = round(Availability * 100, 2),
                Performance = round(Performance * 100, 2),
                Quality = round(Quality * 100, 2)
      | order by timestamp desc
      Visualización en Power BI:
      • Gauge chart con OEE actual por línea
      • Gráfico de línea con tendencia OEE últimas 24h
      • Tabla con top 10 máquinas de mejor/peor rendimiento
      • Alertas automáticas cuando OEE < 75%

      Análisis de anomalías con Real-Time Intelligence

      Detectar patrones anómalos en vibración de motores:
      // Detectar anomalías usando series_decompose_anomalies
      VibrationData
      | where timestamp > ago(7d)
      | make-series vibration_rms = avg(vibration_value) 
          on timestamp 
          from ago(7d) to now() 
          step 1m 
          by machine_id
      | extend anomalies = series_decompose_anomalies(vibration_rms, 1.5)
      | mv-expand timestamp to typeof(datetime), 
                   vibration_rms to typeof(double), 
                   anomalies to typeof(double)
      | where anomalies != 0
      | project timestamp, machine_id, vibration_rms, anomaly_score = anomalies
      | order by timestamp desc
      Alerta automática:
      • Detecta anomalía → Envía notificación Teams
      • Dashboard muestra máquinas con anomalías en rojo
      • Historial de anomalías para análisis de tendencias

      Gemelo Digital con Lakehouse

      Construir historial completo de cada máquina:
      # Notebook en Fabric para crear digital twin
      from pyspark.sql.functions import *
      from pyspark.sql.window import Window
      
      # Leer datos históricos de OneLake
      machine_events = spark.read.format("delta").load("Tables/machine_events")
      maintenance_logs = spark.read.format("delta").load("Tables/maintenance")
      production_logs = spark.read.format("delta").load("Tables/production")
      
      # Crear gemelo digital agregando todas las fuentes
      digital_twin = (
          machine_events
          .join(maintenance_logs, ["machine_id", "date"], "left")
          .join(production_logs, ["machine_id", "date"], "left")
          .groupBy("machine_id")
          .agg(
              first("installation_date").alias("installed_on"),
              sum("runtime_hours").alias("total_runtime_hours"),
              count(when(col("maintenance_type") == "preventive", 1)).alias("preventive_maintenance_count"),
              count(when(col("maintenance_type") == "corrective", 1)).alias("corrective_maintenance_count"),
              sum("pieces_produced").alias("total_pieces_produced"),
              avg("oee").alias("avg_oee"),
              max("timestamp").alias("last_seen")
          )
      )
      
      # Guardar en OneLake
      digital_twin.write.format("delta").mode("overwrite").save("Tables/machine_digital_twin")
      Beneficios del Digital Twin:
      • Historial completo de cada activo (desde instalación)
      • Comparar rendimiento entre máquinas similares
      • Predecir vida útil restante (RUL – Remaining Useful Life)
      • Optimizar calendarios de mantenimiento
      Más información: Lakehouse en Fabric

      Ventajas de Fabric vs soluciones tradicionales

      Característica Fabric Azure Synapse Databricks
      Time-to-insight Minutos Horas Horas
      Configuración Zero-setup Compleja Compleja
      Coste inicial $0 (pay-as-you-go) $$$$ $$$$
      Integración Power BI Nativa Externa Externa
      OneLake Incluido Requiere Data Lake Requiere Delta Lake
      Real-Time KQL Database integrado Azure Stream Analytics (separado) Structured Streaming
      Gobernanza Unificada Multi-servicio Multi-servicio
      Curva aprendizaje Baja (SQL/KQL) Media-Alta Alta (Spark)
      ROI de Fabric para IoT Industrial:
      • 80% reducción en time-to-insight (días → horas)
      • 60% ahorro vs arquitectura tradicional (Synapse + ADF + Power BI)
      • 50% menos recursos de ingeniería de datos necesarios (personas, por si no queda claro).
      • 100% usuarios pueden crear dashboards (vs 10% con SQL)

      Desarrollar un módulo sencillo para Azure IoT Operations

      Hasta ahora hemos hablado de arquitectura, operación y casos de uso, pero falta una pregunta clave si desarrollas: ¿cómo construyo yo un módulo que trabaje con Azure IoT Operations?

      La buena noticia es que IoT Operations no te encierra en un SDK propietario: se apoya en protocolos estándar (MQTT 5.0, HTTP) y en recursos declarativos (CRDs). Eso significa que puedes escribir tus módulos en Python, .NET, Node.js, Go… sin necesidad de un “SDK especial de IoT Operations”.

      La forma más sencilla de empezar es construir un microservicio MQTT que:

      1. Se conecta al broker MQTT de IoT Operations

      2. Se suscribe a un topic industrial (por ejemplo, medidas de vibración)

      3. Aplica una pequeña transformación o lógica

      4. Publica el resultado en otro topic que luego será consumido por un DataFlow

      Ejemplo: módulo de “detección básica de vibración alta” (Python)

      En este ejemplo, vamos a suponer:

      • Broker MQTT de IoT Operations accesible en mqtt://aio-broker:1883 dentro del clúster

      • Topic de origen: opc-ua/robots/+/vibration (datos raw)

      • Topic de salida: analytics/robots/high-vibration (eventos filtrados)

      • Autenticación sencilla por usuario/contraseña (en un entorno real usarías X.509 + TLS)

      Código del módulo (Python + paho-mqtt)

      import json
      import os
      import time
      from paho.mqtt import client as mqtt
      
      MQTT_BROKER_HOST = os.getenv("MQTT_BROKER_HOST", "aio-broker")
      MQTT_BROKER_PORT = int(os.getenv("MQTT_BROKER_PORT", "1883"))
      MQTT_USERNAME = os.getenv("MQTT_USERNAME", "iotops-module")
      MQTT_PASSWORD = os.getenv("MQTT_PASSWORD", "changeme")
      
      INPUT_TOPIC = "opc-ua/robots/+/vibration"
      OUTPUT_TOPIC = "analytics/robots/high-vibration"
      THRESHOLD = float(os.getenv("VIBRATION_THRESHOLD", "0.7"))
      
      def on_connect(client, userdata, flags, reason_code, properties=None):
          print(f"Conectado al broker MQTT con código: {reason_code}")
          client.subscribe(INPUT_TOPIC, qos=1)
      
      def on_message(client, userdata, msg):
          try:
              payload = json.loads(msg.payload.decode("utf-8"))
              vibration = float(payload.get("vibration", 0))
              robot_id = payload.get("robotId", "unknown")
      
              if vibration > THRESHOLD:
                  event = {
                      "robotId": robot_id,
                      "vibration": vibration,
                      "threshold": THRESHOLD,
                      "timestamp": payload.get("timestamp"),
                      "sourceTopic": msg.topic,
                      "severity": "warning"
                  }
                  client.publish(OUTPUT_TOPIC, json.dumps(event), qos=1)
                  print(f"[ALERTA] Vibración alta en {robot_id}: {vibration}")
          except Exception as ex:
              print(f"Error procesando mensaje: {ex}")
      
      def main():
          client = mqtt.Client(client_id="iotops-vibration-analyzer", protocol=mqtt.MQTTv5)
          client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
          client.on_connect = on_connect
          client.on_message = on_message
      
          client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT, keepalive=60)
          client.loop_forever()
      
      if __name__ == "__main__":
          main()

      Este módulo:

      • Se suscribe a las lecturas de vibración

      • Aplica un umbral configurable (VIBRATION_THRESHOLD)

      • Publica solo los eventos relevantes en un topic “limpio” que IoT Operations puede enrutar fácilmente a Event Hubs, Fabric o donde necesites.

      Contenerizar el módulo y desplegarlo en el clúster de IoT Operations

      Dockerfile mínimo:

      FROM python:3.11-slim
      
      WORKDIR /app
      
      RUN pip install paho-mqtt
      
      COPY app.py /app/app.py
      
      ENV MQTT_BROKER_HOST=aio-broker
      ENV MQTT_BROKER_PORT=1883
      ENV MQTT_USERNAME=iotops-module
      ENV MQTT_PASSWORD=changeme
      ENV VIBRATION_THRESHOLD=0.7
      
      CMD ["python", "app.py"]

      Construcción y push al ACR (ejemplo):

      az acr build \
        --registry myacr.azurecr.io \
        --image iotops/vibration-analyzer:1.0 \
        .

      Deployment en Kubernetes (sobre el mismo clúster donde vive IoT Operations):

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: vibration-analyzer
        labels:
          app: vibration-analyzer
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: vibration-analyzer
        template:
          metadata:
            labels:
              app: vibration-analyzer
          spec:
            containers:
            - name: vibration-analyzer
              image: myacr.azurecr.io/iotops/vibration-analyzer:1.0
              env:
              - name: MQTT_BROKER_HOST
                value: "aio-broker-frontend"   # Servicio del broker en IoT Operations
              - name: MQTT_BROKER_PORT
                value: "1883"
              - name: VIBRATION_THRESHOLD
                value: "0.7"
      

      En un entorno más avanzado podrías:

      • Integrar Workload Identity para obtener configuración desde Key Vault

      • Usar TLS y certificados X.509 emitidos por tu PKI

      • Añadir observabilidad con OpenTelemetry y exportar a Prometheus / Grafana

      Encajando el módulo dentro de IoT Operations (DataFlow)

      Una vez que tu módulo esté publicando en analytics/robots/high-vibration, puedes definir un DataFlow de IoT Operations que envíe estos eventos a Event Hubs o Fabric:

      apiVersion: connectivity.iotoperations.azure.com/v1beta1
      kind: DataFlow
      metadata:
        name: high-vibration-alerts
      spec:
        source:
          topic: "analytics/robots/high-vibration"
          qos: 1
        transformation:
          - type: enrichment
            contextQuery: "SELECT robotId, line, location FROM assets"
        destination:
          endpoint: "eventhub-alerts"
          topic: "alerts/robots/high-vibration"

      Con esto ya tenemos el ciclo completo:

      Máquina OPC UA → IoT Operations (MQTT) → Módulo propio → DataFlow → Event Hubs / Fabric / Power BI

      Y, lo más importante: el código de tu módulo es estándar, portable y no depende de un SDK opaco. Si mañana cambias de clúster o de topología, solo cambias la configuración (topics, broker) y sigues trabajando igual.

      Pero si prefieres trabajar con algo aún más nativo

      Puedes elevar tu desarrollo a otro nivel, puedes usar el repositorio oficial Azure IoT Operations SDKs en GitHub: https://github.com/Azure/iot-operations-sdks

      Este SDK —actualmente en preview— ofrece librerías para varios lenguajes (.NET, Go, Rust) que abstraen muchas de las complejidades del broker MQTT, registro de schemas, store de estado, RPC, etc.

      Si tu proyecto lo justifica —alta escala, resiliencia, integración profunda con los servicios de IoT Operations— vale la pena tenerlo en cuenta.

      Mini-ejemplo usando Azure IoT Operations SDK (Preview):

      using Azure.IoTOperations.Client;
      using Azure.IoTOperations.Client.Mqtt;
      using Azure.IoTOperations.Client.Serialization;
      using System.Text.Json;
      
      class TemperaturePayload
      {
          public string DeviceId { get; set; } = "";
          public double Temperature { get; set; }
          public DateTime Timestamp { get; set; }
      }
      
      class TemperatureAlert
      {
          public string DeviceId { get; set; } = "";
          public double Temperature { get; set; }
          public string Severity { get; set; } = "critical";
          public DateTime Timestamp { get; set; }
      }
      
      class Program
      {
          static async Task Main(string[] args)
          {
              var options = new EdgeMqttClientOptions
              {
                  Host = Environment.GetEnvironmentVariable("MQTT_HOST") ?? "aio-broker-frontend",
                  Port = int.Parse(Environment.GetEnvironmentVariable("MQTT_PORT") ?? "1883"),
                  ClientId = "iotops-csharp-module",
                  Username = "moduleuser",
                  Password = "changeme"
              };
      
              var client = new EdgeMqttClient(options);
      
              Console.WriteLine("Conectando al broker MQTT...");
              await client.ConnectAsync();
      
              Console.WriteLine("Suscribiéndose al topic: sensors/temperature/+/plant1");
              await client.SubscribeAsync("sensors/temperature/+/plant1", qos: 1);
      
              client.OnMessageReceived(async (msg) =>
              {
                  try
                  {
                      var payload = JsonSerializer.Deserialize<TemperaturePayload>(msg.Payload);
      
                      if (payload == null)
                          return;
      
                      Console.WriteLine($"Temperatura recibida: {payload.DeviceId} = {payload.Temperature}°C");
      
                      if (payload.Temperature > 80)
                      {
                          var alert = new TemperatureAlert
                          {
                              DeviceId = payload.DeviceId,
                              Temperature = payload.Temperature,
                              Severity = "critical",
                              Timestamp = DateTime.UtcNow
                          };
      
                          var json = JsonSerializer.Serialize(alert);
                          
                          await client.PublishAsync(
                              topic: "alerts/temperature/high",
                              payload: json,
                              qos: 1);
      
                          Console.WriteLine($"[ALERTA] Temperatura alta en {payload.DeviceId}: {payload.Temperature}°C");
                      }
                  }
                  catch (Exception ex)
                  {
                      Console.WriteLine($"Error procesando mensaje: {ex}");
                  }
              });
      
              Console.WriteLine("Módulo C# en ejecución. Ctrl+C para salir.");
              await Task.Delay(Timeout.Infinite);
          }
      }
      

      Dockerfile mínimo:

      FROM mcr.microsoft.com/dotnet/runtime:8.0
      
      WORKDIR /app
      COPY bin/Release/net8.0/publish/ .
      
      ENV MQTT_HOST=aio-broker-frontend
      ENV MQTT_PORT=1883
      
      ENTRYPOINT ["dotnet", "IoTOpsModule.dll"]

      Deployment en Kubernetes:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: iotops-csharp-module
        labels:
          app: iotops-csharp-module
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: iotops-csharp-module
        template:
          metadata:
            labels:
              app: iotops-csharp-module
          spec:
            containers:
            - name: iotops-csharp-module
              image: myacr.azurecr.io/iotops/csharp-module:1.0
              env:
              - name: MQTT_HOST
                value: "aio-broker-frontend"
              - name: MQTT_PORT
                value: "1883"

      Qué aporta usar el SDK en lugar de MQTT.net

      • Los objetos están tipados (clients, mensajes, serialización).

      • Integración directa con IoT Operations Edge Services.

      • Mejor manejo de QoS, reintentos, persistencia y conexión local.

      • Preparado para futuras integraciones nativas:

        • Schema Registry

        • Stateful Apps

        • RPC industrial

        • Broker sidecar services

      Y, sobre todo: te mantienes dentro del modelo operativo oficial de Microsoft para IoT Operations.

      Operar Azure IoT Operations en producción: observabilidad, upgrades y FinOps

      Hasta ahora hemos cubierto arquitectura, despliegue, casos de uso industriales reales, desarrollo de módulos y gobierno declarativo.
      Pero si vienes del mundo OT/IT, sabes que lo difícil no es “desplegar hoy”, sino operar mañana.

      Una plataforma industrial —especialmente un broker MQTT de grado planta montado sobre Kubernetes— exige disciplina operativa. Por eso, esta sección cierra el monográfico con una guía práctica de lo que miran realmente los equipos en producción.

      Observabilidad: lo que de verdad importa en IoT Operations

      Azure IoT Operations vive sobre Kubernetes, pero su observabilidad no es la de “mirar pods y ya”.
      Lo relevante es entender el flujo de datos industrial y asegurar que cada eslabón está sano.

      Métricas críticas del broker MQTT (Frontend y Backend)

      Estas son las señales que indican si tu planta va bien o va a reventar:

      • Mensajes por segundo (ingestión y publicación)

      • Retención en cola / lag del backend (si sube → tienes backpressure)

      • Conexiones activas y sesiones

      • QoS1 inflight mensajes

      • Drop rate (cualquier valor >0 debe investigarse)

      • Throughput por topic (para detectar “tormentas” de sensores)

      Reglas prácticas

      • Si el backend supera el 70% de utilización sostenida: escala.

      • Si inflight QOS1 crece sin bajar: tienes congestión.

      • Si el drop rate crece: algo en la planta está saturado o desincronizado.

      Logs del sistema AIO (Azure IoT Operations)

      Los pods más importantes que debes vigilar:

      • aio-broker-frontend-*

      • aio-broker-backend-*

      • aio-opc-ua-connector-*

      • aio-data-processor-*

      • aio-device-registry-*

      Comandos típicos:

      kubectl logs -n azure-iot-operations -l app=aio-broker-frontend --tail=200 -f
      kubectl get events -n azure-iot-operations
      kubectl describe pod <nombre> -n azure-iot-operations

      Integración con observabilidad cloud

      IoT Operations no trae Grafana ni Prometheus, pero se integra con:

      • Azure Monitor (metrics → Log Analytics)

      • Azure Managed Grafana

      • Prometheus (si lo despliegas tú con scraping sobre AIO)

      En entornos industriales reales, la observabilidad suele cerrarse así:

      • Logs → Log Analytics

      • Métricas técnicas → Prometheus/Grafana

      • Alertas operativas → Azure Monitor / PagerDuty / Teams

      • KPIs industriales → Fabric / Power BI

      Estrategia de upgrades: cómo actualizar sin parar la planta

      El error más común en IoT industrial es asumir que “como es Kubernetes”, ya está todo resuelto.
      La realidad OT es distinta:

      • No puedes reiniciar el broker en mitad de un turno.

      • No puedes perder ingestión.

      • No puedes romper DataFlows que gobiernan la calidad de producción.

      Por eso necesitas un plan formal de upgrade seguro.

      Versionado de CRDs y DataFlows vía GitOps

      Regla de oro:

      En IoT Operations, nada se modifica en producción sin un PR.

      Eso implica:

      • Versionado de DataFlows

      • Versionado de Assets / Device Registry

      • Versionado de endpoints

      • Versionado del propio broker (cambios de particiones / workers)

      GitOps te da:

      • Revisión

      • Auditoría

      • Rollback inmediato

      • Paridad entre entornos

      Cambios de infraestructura bajo control

      Escenarios que requieren cuidado:

      • Aumentar workers del broker backend

      • Cambiar replicas del frontend

      • Modificar retención de mensajes

      • Cambiar estructura de topics o particiones

      Cada modificación debe aplicarse así:

      1. Crear rama → modificar CRD

      2. Validar en staging

      3. Ejecutar prueba sintética de ingestión

      4. Merge → despliegue canary

      5. Monitorear drop rate / lag

      6. Promover a full rollout

      Actualizaciones del propio IoT Operations (módulo AIO)

      Cuando Microsoft publica releases estables.

      La forma recomendable:

      • Blue/green por namespace (dos instancias AIO en paralelo)

      • Traffic shifting por topics

      • Pausar DataFlows si es necesario

      FinOps y dimensionamiento: cuánto cuesta realmente operar IoT Operations

      Este punto se pasa por alto casi siempre, pero en una planta industrial puede significar +500% o –80% de coste según lo hagas bien o mal.

      Tamaño del clúster

      Reglas prácticas basadas en pruebas reales:

      Carga Nodos recomendados RAM por nodo Comentario
      < 200k msg/s 1–2 nodos 16–32 GB Pruebas / pilotos
      200k – 1M msg/s 3 nodos 32 GB Planta mediana
      1M – 5M msg/s 3–5 nodos 64 GB Planta con alta instrumentación
      > 5M msg/s 5–7 nodos 64–96 GB Fábricas automotrices / químicas

      Tip industrial real:

      Los cuellos de botella rara vez están en CPU. Suelen estar en retención del backend, latencia interna o almacenamiento.

      Costes operativos

      Los principales costes:

      1. Clúster IT → Azure Arc + nodos

      2. Event Hubs o IoT Hub (si lo usas como salida)

      3. Fabric (si activas Real-Time + OneLake)

      4. Red (egress si exportas fuera)

      Tus números variarán según los DataFlows, pero como referencia:

      • IoT Hub S2: ~$250/mes

      • Event Hubs Standard: ~$200–400/mes

      • AKS (3 nodos D8s): ~$900/mes

      En la mayoría de plantas:

      IoT Operations cuesta entre $500 y $2,000/mes y sustituye soluciones on-prem de 40–200k€/año.

      Estos números no son teóricos ni académicos: provienen de patrones reales en plantas industriales donde Azure IoT Operations ha reemplazado historiadores propietarios y stacks OT cerrados como OSIsoft PI, AVEVA/Wonderware, Siemens Industrial Edge, Kepware o Ignition con módulos premium. La diferencia de coste y complejidad viene, principalmente, de sustituir licencias cerradas, gateways dedicados y hardware propietario por un clúster Kubernetes estandarizado, escalable y gobernado, sin tarifas por dispositivo ni modelos de licencia por protocolo.

      En entornos donde antes se pagaban 40.000–200.000 €/año en mantenimiento, licencias y appliances, IoT Operations permite operar con un modelo de coste más predecible (compute + eventos) y una arquitectura que crece con la planta en lugar de limitarla.

      IA en Azure IoT Operations: el plano donde la inteligencia ocurre de verdad

      Falta una pieza esencial: la IA. Porque la promesa de IoT industrial no es solo conectar máquinas; es entenderlas, anticiparlas y optimizarlas. Y en ese punto es donde Azure IoT Operations cambia el juego.

      La IA entra en tres niveles:

      IA en el perímetro: inferencia local en tiempo real

      Muchas fábricas necesitan ejecutar modelos cerca de la máquina, no en la nube:

      • Detección de anomalías por vibración

      • Detección visual (calidad, defectos, alineación)

      • Predicción de fallos en robots

      • Control adaptativo de procesos

      • Avisos y alertas de seguridad instantaneos

      En IoT Edge esto era complejo y frágil.

      En IoT Operations, el edge es Kubernetes → puedes desplegar:

      • ONNX Runtime

      • ML.NET

      • contenedores de inferencia

      • modelos PyTorch/TF optimizados

      • runtimes de visión industrial

      Con Scheduling, HA, tolerations y auto-restart: justo lo que una línea productiva necesita.

      Ejemplo de despliegue de inferencia en IoT Operations:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: anomaly-detector
      spec:
        replicas: 3
        template:
          spec:
            containers:
            - name: detector
              image: myacr.azurecr.io/ml/anomaly-detector:1.2
              env:
              - name: MODEL_PATH
                value: "/models/vibration.onnx"

      Aquí la IA vive en la planta: baja latencia, resiliencia y control.

      IA en el Data Processor: enriquecimiento + ML embebido

      Los DataFlows no solo enrutan datos.
      Pueden:

      • aplicar transformaciones complejas

      • generar características (features)

      • ejecutar lógica determinista o estadística

      • preparar datos para modelos

      Dar un vistazo a las ultimas incroporaciones..

      Esto acerca un “mini Spark” al edge, pero diseñado para OT.

      IA en el cloud: aprendizaje, historización y gemelos digitales

      Aquí entra Microsoft Fabric, que ya hemos visto antes:

      • OneLake almacena años de histórico

      • KQL Database ingiere datos en tiempo real

      • Notebooks de Fabric permiten entrenar modelos

      • Se construyen Digital Twins con datos OT

      • Los modelos entrenados se redeployean al edge vía GitOps

      Es el proceso aun más completo:

      Inferencia en el edge → eventos filtrados → Fabric → entrenamiento → despliegue → inferencia renovada

      Ese ciclo automatizable es lo que convierte IoT Operations en una plataforma AI-ready y no solo en un broker MQTT.

      Cierre y siguientes pasos

      Azure IoT Operations no es “otra caja más” en el diagrama, es el plano donde convergen OT, datos e inteligencia. Lleva Kubernetes al perímetro, pone orden en el caos de gateways y data loggers, y abre la puerta a una IA que no vive solo en presentaciones, sino pegada a la línea de producción.

      Si hoy estás en un modelo clásico de IoT Hub + IoT Edge, el camino natural no es “tirarlo todo y empezar de cero”, sino evolucionar de forma pragmática:

      • Empezar por un piloto pequeño en una planta con problemas reales de datos, latencia o mantenimiento.

      • Medir impacto en MTBF, OEE, paradas no planificadas y tiempo de diagnóstico.

      • Escalar después a un modelo híbrido donde IoT Edge cubre sitios pequeños/remotos e IoT Operations se convierte en el “hub industrial” de las plantas grandes.

      A partir de ahí, Microsoft Fabric, la IA en el edge y el modelo declarativo (CRDs + GitOps) hacen el resto: cierran el ciclo completo desde el sensor hasta el gemelo digital, desde la señal cruda hasta la decisión automatizada.

      Este monográfico no pretende cerrar el tema, sino darte lenguaje, arquitectura y ejemplos suficientes para que puedas defender —o cuestionar con criterio— Azure IoT Operations en tu propia realidad industrial. El siguiente paso ya no es leer otro artículo: es elegir una línea de producción, montar un piloto y empezar a poner números encima de la mesa.