En entornos de virtualización Proxmox VE, garantizar la alta disponibilidad de las máquinas virtuales es una prioridad. Aunque Proxmox cuenta con sus propios sistemas de alertas, en ocasiones necesitamos una monitorización externa y centralizada que nos avise de forma inmediata si un servicio se ha detenido. En este artículo, aprenderemos a crear un playbook de Ansible que se conecta a la API de Proxmox, comprueba el estado de un listado de máquinas virtuales y, en caso de detectar que alguna está apagada, envía una alerta instantánea por Telegram a uno o varios técnicos, utilizando variables de Ansible Semaphore para definirlos.
- Arquitectura y flujo de la automatización Ansible/Proxmox/Telegram.
- Configuración del Bot de Telegram y obtención de credenciales.
- Configuración de Variables en Ansible Semaphore.
- El Playbook de Ansible:
comprobar_estado_vm_proxmox_telegram.yml. - Crear tarea en Ansible Semaphore para ejecutar playbook.
- Ejecutar tarea de monitorización de estado de mv y envío de alerta a Telegram.
Arquitectura y flujo de la automatización Ansible/Proxmox/Telegram
La lógica del flujo automatizado que se pretende, se divide en los siguientes pasos:
- Autenticación e interrogación a la API de Proxmox: Ansible realiza una petición segura al cluster de Proxmox usando el módulo
community.general.proxmox_kvm_infopara obtener el estado en tiempo real de toda la infraestructura. - Filtrado condicional en memoria: cruzamos los datos obtenidos de la API con un listado de ID de VM que definimos en Semaphore. Si una de las máquinas de la lista tiene el estado
stopped, se añade a un inventario de fallos. - Notificación multi-chat por Telegram: si la lista de fallos contiene elementos, Ansible interactúa con el Bot de Telegram a través de un bucle (
loop), enviando un mensaje personalizado a cada uno de los identificadores de chat (chat_ids) configurados en las variables del entorno.
Para este propósito, necesitaremos disponer de un servidor Ansible. En el siguiente tutorial explicamos cómo desplegarlo:
Dispondremos de un entorno de virtualización Proxmox VE. En el siguiente tutorial explicamos cómo montar un entorno de virtualización Proxmox VE:
Para la conexión nativa de Ansible con Proxmox, usaremos el API de Proxmox. En el siguiente tutorial explicamos cómo conectar Ansible con Proxmox:
Configuración del Bot de Telegram y obtención de credenciales
Para que Ansible pueda enviar mensajes de forma automática, necesitamos interactuar con la API de Telegram. Esto requiere la creación de un Bot (que nos dará el token) y la obtención del identificador numérico de cada usuario o grupo que recibirá las alertas (chat_id).
1. Crear el Bot de Telegram y obtener el token
Telegram centraliza la creación de bots a través de un bot oficial llamado BotFather. Los pasos son los siguientes:
- Abrimos la aplicación de Telegram y buscamos el usuario @BotFather (asegúrate de que tenga el check azul de cuenta verificada).

- Inicia la conversación y envía el comando:
/newbot - El asistente pedirá un nombre para el bot, por ejemplo:
ProyectoA_Ansible. - Pedirá un nombre de usuario (username) único que obligatoriamente debe terminar en
bot, por ejemplo:ProyectoA_Ansible_Bot. - BotFather devolverá un mensaje de éxito con el HTTP API Token. Tendrá un aspecto similar a este:
1234567890:ABCdefGhIJKlmNoPQRsTUVwxyZ. Lo anotaremos pues lo usaremos más adelante.

⚠️ Advertencia de seguridad: este token es el equivalente a una contraseña maestra para el bot. Cualquiera que lo tenga podrá enviar mensajes en su nombre. Almacénalo de forma segura en las variables de Semaphore.
2. Cómo obtener el chat_id
Para que el bot pueda «hablarle» a un usuario, el usuario debe iniciar conversación primero con el bot por motivos de privacidad. Para ello, desde el Telegram del técnico que quiera recibir las notificaciones, buscaremos el bot creado (por el nombre @ProyectoA_Ansible_Bot)

Para permitir que el bot pueda establecer conversación con el usuario, pulsaremos en INICIAR:

Para obtener el ID de chat de cada técnico que quiera recibir las notificaciones, tras pulsar en INICIAR, escribiremos cualquier mensaje al bot, por ejemplo «hola»:

Y, usando el token, montaremos la siguiente URL:
|
1 |
https://api.telegram.org/botTOKEN_BOT_TELEGRAM/getUpdates |
Y desde el navegador, accederemos a esa URL, nos mostrará un JSON con los datos del mensaje recibido, entre ellos, el chat id, anotaremos este número que necesitaremos más adelante. Realizaremos este proceso por cada usuario que quiera recibir notificaciones. Todos estos ID de chat serán los que anotemos en la variable telegram_chat_ids de Semaphore (como indicamos más adelante):

3. Opción Alternativa: enviar alertas a un Grupo de Telegram
Si en lugar de alertas individuales preferimos que las notificaciones lleguen a un grupo donde esté todo el equipo de técnicos, siguiremos estos pasos:
- Creamos un grupo normal en Telegram y añadimos a los miembros del equipo técnico.
- Añadimos también el bot creado anteriormente como un miembro más del grupo.

- Para obtener el ID del grupo (que a diferencia de los usuarios, suele ser un número negativo), realizamos el mismo proceso que anteriormente para el ID de chat de usuario, aunque en este caso, con que agreguemos el bot al grupo, en la URL, ya nos aparecerá el ID de chat de grupo:

- El ID del grupo lo añadiremos directamente al array de Semaphore, exactamente igual que si fuera el ID de un usuario:
"telegram_chat_ids": [
"-5555543861"
]
Activación del Bot
Antes de lanzar el Playbook de Ansible desde Semaphore, asegúrate de que todos los usuarios configurados (o el grupo) hayan iniciado al bot. Si el bot intenta enviarle un mensaje a un ID que nunca le ha dado a «Iniciar», la API de Telegram rechazará la petición y Ansible devolverá un error de tipo Forbidden: bot can't initiate conversation with a user.
Configuración de Variables en Ansible Semaphore
Para mantener el código limpio, reutilizable y seguro, almacenaremos las credenciales y los parámetros variables en el apartado de Grupos de variables de Semaphore. Para ello, desde Ansible/Semaphore, pulsaremos en «Grupos de variables» y en «Nuevo grupo»

Introduciremos un nombre para el grupo, por ejemplo «», y pulsaremos en JSON, pegando el siguiente contenido (antes cambiaremos los valores de IP del host, usuario API Proxmox, contraseña API, token de Telegram, ID de chats obtenidos anteriormente, ID de las máquinas virtuales a monitorizar, etc. por los específicos de nuestra organización):

El JSON de ejemplo con todas las variables necesarias:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
{ "pve_api_host": "192.168.10.200", "pve_api_user": "api_ansible@pam", "pve_api_token_id": "ansible", "pve_api_token_secret": "af44ddss-sdfsd-fssdf-sdfsdfsdf-fsdf-892742", "pve_nodes": [ "n1", "n2", "n3" ], "telegram_bot_token": "8080855205058:AAasGdfasd8faasdf_asdfMasdfGasdfOasdcfasgdfddasdfsd", "telegram_chat_ids": [ "-5555555561", "11111159" ], "vms_a_monitorear": [ 100, 101, 102 ] } |
Nota técnica: telegram_chat_ids es una lista (array). Esto nos permite añadir tantos ID de usuarios o grupos de Telegram como necesitemos para que la alerta sea multidifusión. Y vms_a_monitorear también es un array, para almacenar los números de VMID de Proxmox a monitorizar.

El Playbook de Ansible: comprobar_estado_vm_proxmox_telegram.yml
Desde el servidor de Ansible, o bien en local o bien en Git (según donde tengamos el repositorio de playbooks), crearemos un nuevo playbook, en este caso en local. Desde el shell del servidor Ansible, en la carpeta de playbooks, crearemos un nuevo fichero YAML:
|
1 |
sudo nano comprobar_estado_vm_proxmox_telegram.yml |
Pegaremos el siguiente código:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
--- - name: Monitorizar estado de VM en Proxmox y notificar por Telegram hosts: localhost gather_facts: no vars: # Inicializamos una lista vacía para acumular los nombres de las VM apagadas vms_apagadas: [] tasks: # ------------------------------------------------------------------------- # TAREA PREVIA: Asegurar librerías requeridas en el venv local de Ansible # ------------------------------------------------------------------------- - name: Asegurar que las librerías de Python requeridas están instaladas ansible.builtin.pip: name: - proxmoxer - requests state: present # Forzamos a que use exactamente el mismo Python ejecutor de Ansible en Semaphore vars: ansible_python_interpreter: "{{ ansible_playbook_python }}" - name: Obtener información de todas las VM de Proxmox mediante la API community.general.proxmox_vm_info: api_host: "{{ pve_api_host }}" api_user: "{{ pve_api_user }}" api_token_id: "{{ pve_api_token_id | default('ansible') }}" api_token_secret: "{{ pve_api_token_secret }}" node: "{{ item }}" validate_certs: no loop: "{{ pve_nodes }}" register: resultados_cluster - name: Filtrar y detectar qué VM de las indicadas en variable semaphore están apagadas set_fact: vms_apagadas: "{{ vms_apagadas + [ item.1.name ] }}" loop: "{{ resultados_cluster.results | subelements('proxmox_vms', skip_missing=True) }}" when: - item.1.vmid | int in vms_a_monitorear - item.1.status == 'stopped' - name: Enviar alerta por Telegram a todos los técnicos configurados en variable semaphore community.general.telegram: token: "{{ telegram_bot_token }}" api_method: sendMessage api_args: chat_id: "{{ item }}" parse_mode: "Markdown" text: | ¡Aviso de PROXMOX! Las siguientes mv están apagadas: {% for vm_name in vms_apagadas %} - {{ vm_name }} {% endfor %} Revise las máquinas, deben estar encendidas. loop: "{{ telegram_chat_ids }}" when: vms_apagadas | length > 0 |
Explicación del playbook anterior:
0. Instalar librerías Python necesarias
En primer lugar, el playbook lanza una tarea de revisión de librerías necesarias, si ya están instaladas pasa a la siguiente tarea, si no lo están, las instala antes de continuar.
1. Extracción de datos limpios (proxmox_kvm_info)
El módulo nativo de Ansible se conecta al puerto 8006 de Proxmox de forma transparente. El resultado devuelto (almacenado en proxmox_info.proxmox_kvm) es una lista de diccionarios que contiene detalles de cada máquina virtual, tales como el vmid, el name (nombre asignado en Proxmox) y el status (running o stopped).
2. Filtro cruzado adaptativo
El filtrado ocurre en esta sección:
|
1 2 3 |
when: - item.vmid | int in vms_a_monitorear - item.status == 'stopped' |
El filtro asegura que Ansible ignore por completo el resto de máquinas del clúster que no nos interesa monitorizar. Aplicamos el filtro | int al vmid debido a que la API de Proxmox a veces devuelve este valor como una cadena de texto (string), garantizando así que la comparación numérica con nuestra lista de Semaphore sea exacta.
3. Plantillas Jinja2 para formatear el mensaje
En lugar de enviar un mensaje molesto por cada máquina caída, usamos un bucle interno estructurado con Jinja2 ({% for vm in vms_apagadas %}) dentro del cuerpo del mensaje de Telegram. Esto unifica todas las alertas en un solo texto limpio y fácil de leer desde la pantalla de bloqueo del teléfono móvil.
4. Automatización multi-usuario con loop
Para lograr que la notificación llegue a varias personas a la vez, mapeamos la directiva loop: "{{ telegram_chat_ids }}" directamente en el módulo de Telegram. Ansible iterará sobre cada ID del array y enviará el mensaje de forma secuencial.
5. Ansible dentro de contenedor docker
En el caso de que Ansible esté en contenedor docker, será necesario incluir en el playbook una comprobación de si existen las colecciones externas community.general, en caso de que no existan, se instalarán automáticamente.
Crear tarea en Ansible Semaphore para ejecutar playbook
Desde Ansible/Semaphore, pulsaremos en «Plantillas de Tareas» y en «Nueva plantilla»:

Pulsaremos en «Ansible Playbook»:

Introduciremos los siguientes datos:
- Nombre: comprobar_estado_vm_proxmox_telegram.
- Ruta del archivo playbook: comprobar_estado_vm_proxmox_telegram.yml.
- Inventario: el inventario no es necesario para esta tarea, dado que tanto la IP del clúster Proxmox, como los servidores (nodos) se indican en variables. Aún así, este campo es obligatorio, por lo que elegiremos cualquier inventario que tengamos.
- Repositorio: Local.
- Grupos de Variables: indicaremos el grupo creado anteriormente «vm_proxmox_telegram».

Ejecutar tarea de monitorización de estado de mv y envío de alerta a Telegram
Ejecutaremos la tarea para realizar una prueba. El playbook accederá a Proxmox, obtendrá el estado de las máquinas virtuales indicadas en variables de Semaphore y si hay alguna detenida, enviará mensaje a los chat de Telegram indicados en variables:

En este caso hay una máquina detenida, por lo que el playbook enviará un mensaje al chat de Telegram indicado en variables. En este ejemplo, enviará chat tanto a un usuario como a un grupo:
