Blog de Amazon Web Services (AWS)
Invoca recursos on-premises de forma interactiva mediante AWS Step Functions y MQTT
Esta publicación está escrita por Alex Paramonov, Arquitecto de Soluciones Sénior para ISV, y Pieter Prinsloo, Gerente de Soluciones para Clientes. Traducida a español por Michael García, Arquitecto de Soluciones.
En ocasiones, las cargas de trabajo en AWS requieren el acceso a los datos almacenados en bases de datos y ubicaciones de almacenamiento on-premises. Las soluciones tradicionales requieren reglas de firewall de entrada, túneles VPN o endpoints públicos para establecer conectividad a recursos on-premises.
Este blog demuestra cómo utilizar el protocolo MQTT (AWS IoT Core) con AWS Step Functions para enviar jobs a recursos on-premises a fin de acceder o recuperar datos almacenados on-premises. La máquina de estados puede comunicarse con recursos on-premises sin abrir puertos de entrada ni endpoints públicos a recursos on-premises. Los recursos pueden correr detrás de enrutadores NAT (Network Address Translation) mientras mantienen la conectividad bidireccional con la nube AWS. Esto provee una manera más segura y costo efectiva para acceder a datos almacenados on-premises.
Descripción general
Al usar Step Functions con AWS Lambda y AWS IoT Core, se puede acceder a los datos almacenados on-premises de forma segura sin alterar la configuración de red existente.
AWS IoT Core permite conectar dispositivos de IoT y enrutar mensajes a servicios de AWS sin administrar la infraestructura. Al utilizar una imagen de contenedor de Docker que se ejecuta on-premises como proxy de IoT Thing, puede aprovechar el broker de mensajería MQTT gestionado de AWS IoT Core para casos de uso ajenos a IoT.
Los subscriptores MQTT reciben información vía tópicos MQTT. Un tópico MQTT actúa como un mecanismo de correspondencia entre publicadores y subscriptores. Conceptualmente, un tópico MQTT actúa como un canal de notificación efímero. Puede crear tópicos a escala prácticamente sin límite en el número de tópicos. En aplicaciones SaaS, por ejemplo, puede crear tópicos por tenant. Aprenda más del diseño tópicos MQTT aquí.
La siguiente arquitectura de referencia muestra el uso de AWS Serverless Application Model (AWS SAM) para la implementación. Step Functions orquesta el flujo de trabajo, AWS Lambda envía y recibe los mensajes on-premises, y AWS IoT Core provee el bróker de mensajes MQTT, gestión de políticas y certificados, y tópicos de publicación/subscripción.
- Inicie la máquina de estados, ya sea “on demand” o programado.
- El estado: “Lambda: Invoke Dispatch Job to On-Premises” publica un mensaje a un bróker de mensajes MQTT en AWS IoT Core.
- El bróker de mensajes envía un mensaje al tópico correspondiente que envía el mensaje al contenedor on-premises que ejecuta el job.
- El contenedor on-premises recibe el mensaje e inicia la ejecución del job. La autenticación se realiza con certificados de cliente y las políticas de seguridad limitan el acceso del contenedor a sólo el tópico correspondiente.
- El contenedor on-premises puede acceder al recurso on-premises cómo una base de datos o ubicaciones de almacenamiento.
- El contenedor on-premises envía los resultados y el estado del job de vuelta hacia otro tópico MQTT.
- La regla de AWS IoT Core invoca la función Lambda “TaskToken Done”.
La función Lambda envía los resultados al Step Functions vía las APIs SendTaskSucess o SendTaskFailure.
Implementación y prueba del ejemplo
Asegúrese de poder administrar los recursos de AWS desde su terminal y de tener:
- Instaladas las últimas versiones de AWS CLI y AWS SAM CLI
- Una cuenta AWS. Si no, visite esta página
- Usuario tiene permisos suficientes para administrar recursos de AWS
- Instalado Git
- Instalado Python versión 3.11 o superior
- Instalado Docker
Puede acceder al repositorio GitHub aquí y seguir los siguientes pasos para desplegar el ejemplo.
El directorio aws-resources contiene los recursos AWS requeridos incluidos en la máquina de estados, funciones Lambda, tópicos y políticas. El directorio on-prem-worker contiene los artefactos de las imágenes Docker. Úselo para ejecutar el contendor on-premises.
En este ejemplo, el contenedor suma dos números, proporcionados como entrada en el siguiente formato:
{
"a": 15,
"b": 42
}
En un escenario real, puede sustituir esta operación con su lógica de negocio. Por ejemplo, recuperar datos desde bases de datos on-premises, generar agregados y enviar los resultados a su máquina de estados.
Siga estos pasos para probar el ejemplo de principio a fin.
Uso de AWS IoT Core sin dispositivos de IoT
No hay dispositivos de IoT en el ejemplo. Sin embargo, el bróker de mensajes MQTT administrado en AWS IoT Core permite enrutar los mensajes hacia servicios AWS sin administrar infraestructura.
AWS IoT Core autentica a los clientes mediante certificados X.509. Puede adjuntar una política a un certificado, permitiendo al cliente publicar y subscribirse solo a determinados tópicos. Este enfoque no requiere de credenciales IAM dentro del contenedor on-premises.
La seguridad, eficiencia en costos, infraestructura administrada y escalabilidad de AWS IoT Core lo convierten en una buena opción para muchas aplicaciones híbridas más allá de los casos de uso típicos de IoT.
Envío de jobs desde Step Functions y espera de una respuesta
Cuando una máquina de estados alcanza la tarea para enviar el job a un entorno on-premises, la ejecución se detiene y espera hasta que el job finalice. Step Functions soporta 3 patrones de integración: Request-Response, Sync Run a Job y Wait for a Callback with Task Token. El ejemplo utiliza la Integración “Wait for a Callback with Task Token”. Esta permite detener el job y esperar por una llamada de callback hasta por 1 año.
Cuando el entorno on-premises completa el job, publica un mensaje a un tópico en AWS IoT Core. Una regla de AWS IoT Core invoca una función Lambda, qué envía el resultado de vuelta a la máquina de estados mediante una llamada a las APIs SendTaskSuccess o SendTaskFailure en Step Functions.
Puede prevenir que se agote el tiempo de espera de la máquina de estados al agregar HeartBeatSeconds a la tarea en el Amazon State Language (ASL). Los tiempos de espera se agotan si el job se congela y la API SendTaskFailure no es invocada. HeartbeatSeconds envía heartbeats vía llamada a la API SendTaskHeartbeat, que debería ser menor que el TimeoutSeconds definido.
Para crear una tarea en ASL para su máquina de estados, qué espera por un token de callback, utilice el siguiente código:
{
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "${LambdaNotifierToWorkerArn}",
"Payload": {
"Input.$": "$",
"TaskToken.$": "$$.Task.Token"
}
}
El sufijo .waitForTaskToken
indica que la tarea debe esperar una llamada de callback. La máquina de estados genera un token de callback único, al que se puede acceder mediante la variable $$.Task.Token,
y lo pasa como entrada a la función de Lambda definida en FunctionName.
A continuación, la función Lambda envía el token hacia el entorno on-premises vía un tópico en AWS IoT Core.
Lambda no es el único servicio que soporta la integración de tipo “Wait for Callback”. Para ver la lista completa ingrese aquí.
Además de enviar tareas y recuperar los resultados, puede implementar mecanismos de seguimiento y cierre. Para hacer un seguimiento, se puede enviar métricas vía un tópico separado.
Según su implementación actual, tiene varias opciones:
- Almacenar los datos del progreso en Amazon DynamoDB y visualizarlo mediante llamadas de API REST a funciones Lambda, que lee una tabla de DynamoDB. Consulte este tutorial sobre cómo almacenar datos en DynamoDB directamente desde el tópico.
- Para una experiencia de usuario reactiva, cree una regla para invocar una función Lambda cuando lleguen nuevos datos de progreso. Abra una conexión WebSocket hacia su backend. La función Lambda envía los datos de progreso vía WebSockets directamente al frontend.
Para implementar un mecanismo de cierre, puede ejecutar los jobs en hilos separados en su entorno y suscribirse al tópico (en el que su máquina de estados publica los mensajes de cierre). Si llega un mensaje de cierre, termine el hilo en su entorno y devuelva el estado incluyendo el token de callback de la tarea.
Uso de reglas de AWS IoT core y funciones de Lambda
Un mensaje con los resultados del job desde su entorno no llega a la API de Step Functions directamente. En su lugar, una regla de AWS IoT Core y una función de Lambda reenvían el mensaje hacia Step Functions. Esto permite permisos más granulares en las políticas de AWS IoT Core, lo que se traduce en una mayor seguridad porque el contenedor solo puede publicar y suscribirse a tópicos específicos. No existen credenciales de IAM on-premise.
El rol de ejecución de la función Lambda contiene sólo los permisos para las llamadas de API SendTaskSuccess, SendTaskHeartbeat, y SendTaskFailure.
Como alternativa, un entorno puede ejecutar llamadas a las APIs de los flujos en Step Functions, lo que elimina la necesidad de un tópico de AWS IoT Core, una regla y una función Lambda para invocar a las APIs de Step Functions. Este enfoque requiere credenciales IAM dentro del contenedor. Puede utilizar AWS Identity and Access Management Roles Anywhere para obtener credenciales de seguridad temporales. A medida que la funcionalidad de su entorno evoluciona con el tiempo, puede añadir más llamadas a la API de AWS mientras añade permisos al rol de ejecución de IAM.
Limpieza
Los servicios utilizados en esta solución son aptos para la capa gratuita de AWS. Para limpiar los recursos del directorio aws-resources/, ejecute:
sam delete
Esto elimina todos los recursos aprovisionados por el archivo template.yml.
Para eliminar el certificado de cliente de AWS, vaya a AWS IoT Core Certificates y elimine el certificado, que agregó durante los pasos de implementación manual.
Por último, detenga el contenedor de Docker de forma local y elimínelo:
docker rm --force mqtt-local-client
Finalmente, elimine la imagen del contenedor:
docker rmi mqtt-client-waitfortoken
Conclusión
Acceder a los recursos on-premises con entornos controlados vía Step Functions utilizando MQTT y AWS IoT Core es una manera segura, reactiva y costo efectiva para ejecutar sus cargas on-premises. Considere actualizar sus cargas de trabajo híbridas que utilizan sondeos o programaciones hacia el enfoque reactivo descrito en este blog. Esto ofrece una experiencia de usuario mejorada con un rápido envío y seguimiento de sus jobs fuera de la nube.
Para obtener más recursos de aprendizaje serverless, visite Serverless Land.