Descubre cómo Rundeck transforma la automatización de operaciones, además de mi imagen Docker personalizada y plugin de transferencia de archivos entre nodos para entornos de producción.
Hay un momento que todo ingeniero de operaciones conoce bien: son las 2 AM, algo está roto, y estás frenéticamente conectándote por SSH a servidores tratando de recordar la secuencia exacta de comandos para arreglarlo. Ya lo has hecho antes, pero ¿era primero systemctl restart o la actualización de configuración? ¿Y en qué servidores exactamente?
Este es el problema que Rundeck resuelve. Es una plataforma de automatización de runbooks de código abierto que te permite definir, programar y ejecutar procedimientos operacionales en toda tu infraestructura—con control de acceso adecuado, registros de auditoría, y la tranquilidad de saber que el procedimiento se ejecutará exactamente de la misma manera cada vez.
He estado usando Rundeck durante años, y recientemente decidí contribuir al ecosistema creando tres herramientas que resuelven puntos de dolor específicos que encontré: una imagen Docker lista para producción, un plugin para copiar archivos entre nodos, y una GitHub Action para integración CI/CD sin fricciones. Permíteme guiarte a través de todas ellas.
Rundeck ocupa un espacio único en la cadena de herramientas DevOps. No es una herramienta de gestión de configuración como Ansible o Puppet—aunque se integra perfectamente con ellas. No es una plataforma CI/CD como Jenkins—aunque puede disparar y ser disparado por pipelines. Rundeck está diseñado específicamente para flujos de trabajo operacionales.
En mi experiencia, Rundeck sobresale en:
Una de las características más poderosas de Rundeck es su API REST completa. Cada acción que puedes realizar en la interfaz web está disponible programáticamente, haciendo de Rundeck un backend perfecto para operaciones automatizadas.
La API soporta:
Rundeck soporta múltiples métodos de autenticación para acceso a la API:
# Usando Token de API (recomendado)
curl -H "X-Rundeck-Auth-Token: TU_TOKEN" \
https://rundeck.example.com/api/41/projects
# Usando cookie de sesión
curl -c cookies.txt -b cookies.txt \
-d "j_username=admin&j_password=admin" \
https://rundeck.example.com/j_security_check
# Ejecutar un job por ID
curl -X POST \
-H "X-Rundeck-Auth-Token: TU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"options": {"environment": "production", "version": "1.2.3"}}' \
https://rundeck.example.com/api/41/job/JOB_ID/run
# La respuesta incluye el ID de ejecución para monitoreo
{
"id": 12345,
"href": "https://rundeck.example.com/api/41/execution/12345",
"status": "running"
}
Pipelines CI/CD
Dispara jobs de despliegue desde Jenkins, GitHub Actions o GitLab CI. Creé una GitHub Action dedicada para hacer esta integración aún más fácil: rundeck-github-action .
# Usando la Rundeck GitHub Action
- name: Desplegar via Rundeck
uses: Walsen/rundeck-github-action@v1
with:
rundeck_url: https://rundeck.example.com
rundeck_token: ${{ secrets.RUNDECK_TOKEN }}
action: run_job
job_id: ${{ vars.DEPLOY_JOB_ID }}
job_options: '{"version": "${{ github.sha }}", "environment": "production"}'
wait_for_completion: true
timeout: 600
La action soporta múltiples operaciones:
| Acción | Descripción |
|---|---|
run_job |
Ejecutar un job de Rundeck con opciones |
get_job_info |
Obtener detalles del job |
list_jobs |
Listar jobs en un proyecto |
get_execution |
Obtener detalles de ejecución |
list_executions |
Listar ejecuciones de un job o proyecto |
abort_execution |
Abortar una ejecución en curso |
También puedes esperar a que el job complete y obtener el estado de ejecución:
- name: Ejecutar despliegue y esperar
id: deploy
uses: Walsen/rundeck-github-action@v1
with:
rundeck_url: https://rundeck.example.com
rundeck_token: ${{ secrets.RUNDECK_TOKEN }}
action: run_job
job_id: ${{ vars.DEPLOY_JOB_ID }}
wait_for_completion: true
- name: Verificar resultado
run: |
echo "Estado: ${{ steps.deploy.outputs.execution_status }}"
echo "URL: ${{ steps.deploy.outputs.execution_url }}"
Integración con Monitoreo
Haz que tu sistema de monitoreo ejecute jobs de recuperación automáticamente:
# Ejemplo de handler de webhook de PagerDuty
def handle_alert(alert):
if alert['type'] == 'high_memory':
requests.post(
f"{RUNDECK_URL}/api/41/job/{CLEAR_CACHE_JOB}/run",
headers={"X-Rundeck-Auth-Token": RUNDECK_TOKEN},
json={"options": {"server": alert['hostname']}}
)
Agentes de IA e Integración con LLM
Aquí es donde las cosas se ponen interesantes. La API de Rundeck lo convierte en un backend de ejecución ideal para operaciones impulsadas por IA. Usando el SDK de Strands Agents de AWS, puedes construir agentes inteligentes que aprovechan Rundeck como su columna vertebral operacional.
Primero, instala las dependencias:
pip install strands-agents strands-agents-tools requests
Crea una herramienta Rundeck personalizada para tu agente:
from strands import Agent, tool
import requests
RUNDECK_URL = "https://rundeck.example.com"
RUNDECK_TOKEN = "tu-token-api"
@tool
def list_rundeck_jobs(project: str) -> dict:
"""Lista los runbooks disponibles en un proyecto de Rundeck.
Args:
project: El nombre del proyecto de Rundeck
Returns:
Lista de jobs disponibles con sus IDs y descripciones
"""
response = requests.get(
f"{RUNDECK_URL}/api/41/project/{project}/jobs",
headers={"X-Rundeck-Auth-Token": RUNDECK_TOKEN}
)
return response.json()
@tool
def run_rundeck_job(job_id: str, options: dict = None) -> dict:
"""Ejecuta un job/runbook de Rundeck.
Args:
job_id: El UUID del job a ejecutar
options: Parámetros opcionales para el job
Returns:
Detalles de ejecución incluyendo estado e ID de ejecución
"""
response = requests.post(
f"{RUNDECK_URL}/api/41/job/{job_id}/run",
headers={
"X-Rundeck-Auth-Token": RUNDECK_TOKEN,
"Content-Type": "application/json"
},
json={"options": options or {}}
)
return response.json()
@tool
def get_execution_status(execution_id: int) -> dict:
"""Verifica el estado de una ejecución de job de Rundeck.
Args:
execution_id: El ID de ejecución a verificar
Returns:
Estado y detalles de la ejecución
"""
response = requests.get(
f"{RUNDECK_URL}/api/41/execution/{execution_id}",
headers={"X-Rundeck-Auth-Token": RUNDECK_TOKEN}
)
return response.json()
# Crear el agente de operaciones
ops_agent = Agent(
system_prompt="""Eres un asistente de operaciones con acceso a runbooks de Rundeck.
Cuando te pidan realizar tareas operacionales:
1. Lista los jobs disponibles para encontrar el runbook apropiado
2. Ejecuta el job con los parámetros correctos
3. Monitorea la ejecución y reporta los resultados
Siempre confirma antes de ejecutar operaciones destructivas.""",
tools=[list_rundeck_jobs, run_rundeck_job, get_execution_status]
)
# Ejemplo de interacción
response = ops_agent("Los servidores de aplicación están quedándose sin espacio en disco. \
¿Puedes limpiar los archivos de log en el cluster de producción?")
print(response)
Este patrón mantiene a los humanos en control—la IA solo puede ejecutar runbooks pre-aprobados con controles de acceso y registros de auditoría adecuados. Es operaciones autónomas con “guardrails”. El agente puede razonar sobre qué runbook usar, ejecutarlo y reportar los resultados, todo mientras respeta las políticas RBAC de Rundeck.
Integración Low-Code con n8n
Si prefieres un enfoque visual para la automatización, n8n ofrece integración nativa con Rundeck. Puedes construir flujos de trabajo que conecten eventos de GitHub con ejecuciones de jobs de Rundeck sin escribir código.
El nodo Rundeck de n8n soporta:
Combinado con las más de 400 integraciones de n8n, puedes crear cadenas de automatización poderosas—por ejemplo, disparar un job de despliegue cuando se publica un release en GitHub, y luego notificar a tu equipo en Slack cuando complete.
Rundeck sigue un modelo open-core. La edición comunitaria es completamente de código abierto bajo la licencia Apache 2.0, mientras que PagerDuty (quien adquirió Rundeck) ofrece versiones comerciales con características adicionales.
Gratis para siempre, incluye:
Esto es lo que usa mi imagen Docker—perfecto para equipos pequeños a medianos y entornos de aprendizaje.
Las ofertas enterprise agregan:
| Característica | Descripción |
|---|---|
| Alta Disponibilidad | Despliegues en cluster con auto-takeover |
| Integración SSO | Soporte SAML, LDAP, OAuth |
| Plugins Enterprise | Integraciones con ServiceNow, PagerDuty, Datadog, VMware |
| Programación Avanzada | Calendarios de blackout, pronóstico de programación |
| Reanudación de Jobs Fallidos | Reanudar desde el paso fallido en lugar de reiniciar |
| Soporte Enterprise | Soporte respaldado por SLA y gestión de cuenta |
PagerDuty ofrece dos opciones comerciales:
Para la mayoría de los casos de uso, comienza con la versión open source. Está lista para producción y cubre la funcionalidad principal. Considera actualizar cuando necesites:
La versión open source no es una versión “lite”—es una plataforma de operaciones completa que muchas organizaciones ejecutan exitosamente en producción.
Mientras construía un flujo de trabajo de distribución de configuración, encontré una limitación. El plugin copiador de archivos integrado de Rundeck mueve archivos desde el servidor Rundeck hacia los nodos destino. Pero necesitaba copiar archivos de un nodo a múltiples otros nodos—específicamente, distribuyendo configuraciones generadas desde un servidor central hacia nodos de aplicación.
La solución alternativa era torpe: descargar a Rundeck, luego subir a cada destino. Para archivos grandes o muchos destinos, esto se convierte en un cuello de botella.
Así que construí un plugin.
El plugin rundeck-node-to-node agrega un paso de flujo de trabajo que copia archivos y directorios entre nodos usando SSH/SFTP, completamente integrado con las definiciones de nodos y almacenamiento de claves de Rundeck.
Via-Rundeck (Por Defecto)
Los archivos se descargan a Rundeck una vez, luego se suben a todos los destinos. Funciona en cualquier topología de red.
Modo Directo
El origen envía directamente a los destinos via SCP. Más rápido, pero requiere acceso SSH del origen a los destinos.
El plugin usa los atributos estándar de nodos de Rundeck:
config-server:
hostname: 10.0.1.10
username: deploy
ssh-key-storage-path: keys/project/deploy-key
tags: config
app-server-01:
hostname: 10.0.1.20
username: deploy
ssh-key-storage-path: keys/project/deploy-key
tags: app,production
app-server-02:
hostname: 10.0.1.21
username: deploy
ssh-key-storage-path: keys/project/deploy-key
tags: app,production
| Opción | Requerido | Por Defecto | Descripción |
|---|---|---|---|
| Source Node | Sí | - | Nombre del nodo donde se originan los archivos |
| Source Path | Sí | - | Ruta del archivo o directorio en el origen |
| Destination Nodes | Sí | - | Nombres de nodos destino separados por coma |
| Destination Path | Sí | - | Ruta destino en los nodos |
| Recursive Copy | No | true | Copiar directorios recursivamente |
| Preserve Attributes | No | true | Mantener timestamps y permisos |
| Transfer Mode | No | via-rundeck | via-rundeck o direct |
| Parallel Transfers | No | true | Transferir a múltiples nodos en paralelo |
| Continue on Error | No | false | No fallar si algunos destinos fallan |
libext de RundeckEl plugin aparece como un nuevo tipo de paso de flujo de trabajo: “Node to Node File Copy”.
Instalar Rundeck tradicionalmente significa lidiar con Java, bases de datos, proxies reversos y gestión de procesos. Para simplificar esto, creé una imagen Docker que empaqueta todo para uso en producción.
La rundeck-image provee:
docker run -d \
-p 8080:8080 \
-e RUNDECK_GRAILS_URL=http://localhost:8080 \
ghcr.io/walsen/rundeck-image:latest
Accede a Rundeck en http://localhost:8080.
version: '3.8'
services:
rundeck:
image: ghcr.io/walsen/rundeck-image:latest
ports:
- "8080:8080"
environment:
RUNDECK_GRAILS_URL: https://rundeck.example.com
RUNDECK_DATABASE_URL: jdbc:postgresql://db:5432/rundeck
RUNDECK_DATABASE_USERNAME: rundeck
RUNDECK_DATABASE_PASSWORD: ${DB_PASSWORD}
volumes:
- ./config/realm.properties:/etc/rundeck/realm.properties
- rundeck-data:/var/rundeck
depends_on:
- db
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: rundeck
POSTGRES_USER: rundeck
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
rundeck-data:
postgres-data:
| Variable | Por Defecto | Descripción |
|---|---|---|
RUNDECK_GRAILS_URL |
http://localhost:8080 |
URL externa (debe coincidir con tu configuración) |
RUNDECK_DATABASE_URL |
- | Cadena de conexión JDBC de PostgreSQL |
RUNDECK_DATABASE_USERNAME |
- | Usuario de base de datos |
RUNDECK_DATABASE_PASSWORD |
- | Contraseña de base de datos |
Monta un archivo realm.properties para autenticación básica:
# usuario:contraseña,rol1,rol2
admin:admin,user,admin
operator:operator123,user
readonly:viewer456,user
Para producción, integra con LDAP o SSO—Rundeck soporta ambos.
La imagen maneja cualquier puerto externo. Solo haz coincidir RUNDECK_GRAILS_URL:
# Ejecutando en puerto 4440
docker run -d \
-p 4440:8080 \
-e RUNDECK_GRAILS_URL=http://localhost:4440 \
ghcr.io/walsen/rundeck-image:latest
Permíteme mostrar cómo estas herramientas trabajan juntas en un escenario real.
La Configuración:
El Flujo de Trabajo:
Configuración del Job:
| Paso | Nodo(s) | Acción |
|---|---|---|
| 1 | config-server | /opt/scripts/generate-config.sh |
| 2 | config-server → app-01..05 | Copia Node-to-Node /etc/myapp/config.yml |
| 3 | app-01..05 (secuencial) | systemctl reload myapp |
El Resultado:
El repositorio del plugin incluye un entorno de prueba basado en Docker:
cd test/
docker-compose up -d
Esto levanta:
Ver test/README.md para instrucciones detalladas de prueba.
Ambos repositorios incluyen flujos de trabajo de GitHub Actions:
rundeck-image:
rundeck-node-to-node:
Si estás ejecutando en AWS, tienes varias opciones para desplegar Rundeck. Aquí está mi recomendación basada en costo y esfuerzo operacional:
Para la mayoría de los equipos, ECS Fargate alcanza el punto óptimo entre costo y simplicidad operacional:
| Factor | ECS Fargate |
|---|---|
| Esfuerzo Operacional | Bajo - sin instancias EC2 que gestionar |
| Costo | ~$30-50/mes para cargas pequeñas |
| Escalado | Escalado horizontal fácil |
| Integración | ALB nativo, Secrets Manager, CloudWatch |
| Persistencia | EFS para datos de Rundeck, RDS para base de datos |
Para despliegues conscientes del costo, puedes ejecutar PostgreSQL como un contenedor sidecar en lugar de usar RDS. Esto reduce costos significativamente mientras mantiene un enfoque containerizado:
| Factor | Con RDS | Con PostgreSQL Sidecar |
|---|---|---|
| Costo Mensual | $50-80 | $20-35 |
| Backups de BD | Automáticos | Manuales (snapshots EFS) |
| Alta Disponibilidad | Opción RDS Multi-AZ | Contenedor único |
| Complejidad | Dos servicios | Una sola tarea |
Para la mayoría de los despliegues de Rundeck, el enfoque sidecar funciona muy bien—Rundeck no es una carga de trabajo de alta transacción, y EFS proporciona durabilidad para tus datos.
| Opción | Costo Mensual | Esfuerzo Ops | Mejor Para |
|---|---|---|---|
| EC2 (t3.small) | $15-20 | Medio | Presupuesto ajustado, cargas 24/7 |
| EC2 Spot | $5-10 | Medio | Dev/test, tolera interrupciones |
| Lightsail | $5-20 | Bajo | Aprendizaje, configuraciones simples |
| ECS Fargate | $30-50 | Bajo | Producción, bajo mantenimiento |
| EKS | $100+ | Alto | Ya tienes Kubernetes |
{
"family": "rundeck",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "2048",
"containerDefinitions": [
{
"name": "rundeck",
"image": "ghcr.io/walsen/rundeck-image:latest",
"portMappings": [
{"containerPort": 8080, "protocol": "tcp"}
],
"environment": [
{"name": "RUNDECK_GRAILS_URL", "value": "https://rundeck.example.com"}
],
"secrets": [
{"name": "RUNDECK_DATABASE_URL", "valueFrom": "arn:aws:secretsmanager:..."},
{"name": "RUNDECK_DATABASE_PASSWORD", "valueFrom": "arn:aws:secretsmanager:..."}
],
"mountPoints": [
{"sourceVolume": "rundeck-data", "containerPath": "/var/rundeck"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/rundeck",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"volumes": [
{
"name": "rundeck-data",
"efsVolumeConfiguration": {
"fileSystemId": "fs-xxxxxxxx",
"transitEncryption": "ENABLED"
}
}
]
}
Esta configuración te da un despliegue de Rundeck listo para producción con almacenamiento persistente, gestión de secretos y logging centralizado—todo con mínimo overhead operacional.
Rundeck transforma el caos operacional en procedimientos repetibles y auditables. Es la herramienta a la que recurro cuando necesito cerrar la brecha entre “deberíamos automatizar esto” y “tenemos tiempo para construir automatización adecuada.”
El plugin Node-to-Node llena una brecha específica—distribución eficiente de archivos entre nodos sin enrutar todo a través de Rundeck. Y la imagen Docker elimina la fricción de poner en funcionamiento una instancia de Rundeck lista para producción.
Si te estás ahogando en trabajo operacional repetitivo, dale una oportunidad a Rundeck. Y si necesitas estas capacidades específicas, las herramientas están listas para ti.
Keyboard Shortcuts
| Command | Function |
|---|---|
| ? (Shift+/) | Bring up this help modal |
| g+h | Go to Home |
| g+p | Go to Posts |
| g+e | Open Editor page on GitHub in a new tab |
| g+s | Open Source page on GitHub in a new tab |
| r | Reload page |