Rundeck es una plataforma de automatización de operaciones: centraliza comandos, scripts y runbooks, los ejecuta por SSH en tus servidores y deja registro de quién lanzó qué y con qué resultado. En este tutorial instalarás Rundeck Community en Ubuntu 24.04 con PostgreSQL como base de datos, lo publicarás detrás de Nginx con HTTPS, darás de alta nodos remotos, crearás un runbook de respuesta a incidentes y definirás un grupo de operadores que solo puede ejecutar jobs.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS y al menos 2 GB de RAM (4 GB recomendados), por ejemplo un VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Un dominio con un registro A apuntando a la IP del servidor, por ejemplo rundeck.your_domain.
  • Los puertos 22, 80 y 443 abiertos en UFW.
  • Uno o varios servidores Linux que quieras gestionar, accesibles por SSH desde el servidor de Rundeck.

Paso 1: Instalar Java y PostgreSQL

Rundeck es una aplicación Java y en su versión 5 funciona con Java 17. Instala el runtime sin interfaz gráfica y PostgreSQL:

sudo apt update
sudo apt install openjdk-17-jre-headless postgresql

Comprueba la versión de Java:

java -version
openjdk version "17.0.x" ...

Por defecto Rundeck usa una base de datos H2 embebida, válida solo para pruebas. Crea un usuario y una base de datos en PostgreSQL. Sustituye your_strong_password por una contraseña robusta:

sudo -u postgres psql -c "CREATE USER rundeck WITH PASSWORD 'your_strong_password';"
sudo -u postgres psql -c "CREATE DATABASE rundeck OWNER rundeck;"

Paso 2: Añadir el repositorio de Rundeck e instalar el paquete

PagerDuty publica los paquetes de Rundeck en su propio repositorio. Descarga la clave en /etc/apt/keyrings:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://packages.rundeck.com/pagerduty/rundeck/gpgkey | sudo gpg --dearmor -o /etc/apt/keyrings/rundeck.gpg

Crea el archivo del repositorio:

echo "deb [signed-by=/etc/apt/keyrings/rundeck.gpg] https://packages.rundeck.com/pagerduty/rundeck/any/ any main" | sudo tee /etc/apt/sources.list.d/rundeck.list

Instala Rundeck:

sudo apt update
sudo apt install rundeck

El paquete crea el usuario de sistema rundeck, la configuración en /etc/rundeck/, los datos en /var/lib/rundeck/ y los logs en /var/log/rundeck/. No arranques todavía el servicio: primero lo conectarás a PostgreSQL para que no cree sus tablas en H2.

Paso 3: Configurar la base de datos y la URL pública

Abre el archivo de configuración principal:

sudo nano /etc/rundeck/rundeck-config.properties

Localiza las líneas grails.serverURL y dataSource.url y deja el bloque así, con tu dominio y la contraseña del paso 1:

grails.serverURL=https://rundeck.your_domain
server.address=127.0.0.1

dataSource.dbCreate = none
dataSource.driverClassName = org.postgresql.Driver
dataSource.url = jdbc:postgresql://localhost/rundeck
dataSource.username = rundeck
dataSource.password = your_strong_password
  • grails.serverURL es la URL que Rundeck usa en enlaces, redirecciones y webhooks. Debe coincidir con la que escribirá el navegador.
  • server.address=127.0.0.1 hace que Rundeck escuche solo en local en el puerto 4440; el acceso desde fuera pasará por Nginx.

Este archivo contiene una contraseña, así que restringe sus permisos:

sudo chown rundeck:rundeck /etc/rundeck/rundeck-config.properties
sudo chmod 640 /etc/rundeck/rundeck-config.properties

Paso 4: Cambiar la contraseña del administrador

Los usuarios locales se definen en /etc/rundeck/realm.properties con el formato usuario:contraseña,rol1,rol2. La instalación trae admin con contraseña admin. Cámbiala antes del primer arranque:

sudo nano /etc/rundeck/realm.properties
admin:your_admin_password,user,admin

Aprovecha para crear un usuario operador que usarás en el paso 9:

operador1:your_operator_password,user,operadores

Protege el archivo:

sudo chown rundeck:rundeck /etc/rundeck/realm.properties
sudo chmod 640 /etc/rundeck/realm.properties

Paso 5: Arrancar Rundeck

El servicio se llama rundeckd. Habilítalo y arráncalo:

sudo systemctl enable --now rundeckd

El primer arranque tarda uno o dos minutos porque crea el esquema en PostgreSQL. Sigue el log hasta ver el mensaje de que el servidor está listo:

sudo tail -f /var/log/rundeck/service.log
Grails application running at http://127.0.0.1:4440 in environment: production

Pulsa Ctrl+C y comprueba que escucha en local:

sudo ss -tlnp | grep 4440
LISTEN 0  100  127.0.0.1:4440  0.0.0.0:*  users:(("java",pid=...))

Paso 6: Publicar Rundeck con Nginx y HTTPS

Instala Nginx y Certbot:

sudo apt install nginx certbot python3-certbot-nginx

Crea el sitio:

sudo nano /etc/nginx/sites-available/rundeck
server {
    listen 80;
    server_name rundeck.your_domain;

    location / {
        proxy_pass http://127.0.0.1:4440;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }
}

Actívalo, valida la sintaxis y recarga:

sudo ln -s /etc/nginx/sites-available/rundeck /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Abre HTTP y HTTPS en el firewall y obtén el certificado de Let's Encrypt:

sudo ufw allow 'Nginx Full'
sudo certbot --nginx -d rundeck.your_domain

Abre https://rundeck.your_domain en el navegador e inicia sesión como admin con la contraseña del paso 4. Si tras el login te redirige a http:// o a localhost, revisa grails.serverURL.

Paso 7: Crear un proyecto y dar de alta nodos

En Rundeck todo vive dentro de un proyecto: jobs, nodos, claves y webhooks. Pulsa New Project, llámalo infraestructura y guarda.

Preparar el acceso SSH a los nodos

Rundeck se conecta a cada nodo por SSH con una clave. Genera un par de claves dedicado en el servidor de Rundeck:

sudo -u rundeck ssh-keygen -t ed25519 -f /var/lib/rundeck/.ssh/id_ed25519_nodos -N "" -C "rundeck"

En cada nodo gestionado, crea un usuario deploy y añade la clave pública (/var/lib/rundeck/.ssh/id_ed25519_nodos.pub) a /home/deploy/.ssh/authorized_keys. Desde el servidor de Rundeck, comprueba la conexión y acepta la huella del host:

sudo -u rundeck ssh -i /var/lib/rundeck/.ssh/id_ed25519_nodos deploy@your_node_ip hostname
web-01

Ahora sube la clave privada al almacén de claves de Rundeck para no referenciar archivos del disco. En el proyecto, ve a Project Settings > Key Storage > Add or Upload a Key, elige Private Key, pega el contenido de /var/lib/rundeck/.ssh/id_ed25519_nodos y guárdala con el nombre deploy en la ruta que propone (keys/project/infraestructura/). La ruta completa será keys/project/infraestructura/deploy.

Definir el inventario de nodos

Crea un archivo YAML con los nodos. Cada nodo lleva etiquetas (tags) que después usarás para filtrar:

sudo mkdir -p /etc/rundeck/nodes
sudo nano /etc/rundeck/nodes/infraestructura.yaml
web-01:
  nodename: web-01
  hostname: 203.0.113.10
  username: deploy
  osFamily: unix
  tags: web,produccion
  ssh-key-storage-path: keys/project/infraestructura/deploy

web-02:
  nodename: web-02
  hostname: 203.0.113.11
  username: deploy
  osFamily: unix
  tags: web,produccion
  ssh-key-storage-path: keys/project/infraestructura/deploy
sudo chown -R rundeck:rundeck /etc/rundeck/nodes

En el proyecto, ve a Project Settings > Edit Nodes > Add a new Node Source, elige File, formato resourceyaml y ruta /etc/rundeck/nodes/infraestructura.yaml. Guarda y abre Nodes: al filtrar por tags: web deben aparecer web-01 y web-02.

Para probar la conexión, ve a Commands, escribe el filtro tags: web, el comando uptime y pulsa Run on 2 Nodes. Deberías ver la salida de cada servidor.

Paso 8: Crear un runbook de respuesta a incidentes

Un runbook es un job que recoge el procedimiento que el equipo seguiría a mano. Este ejemplo diagnostica un servidor web y, si se lo pides, reinicia un servicio. Guárdalo en tu equipo como runbook-web.yaml:

- name: "Runbook: servidor web degradado"
  description: Recoge diagnóstico y opcionalmente reinicia el servicio indicado
  loglevel: INFO
  executionEnabled: true
  nodeFilterEditable: true
  nodefilters:
    filter: "tags: web"
  options:
    - name: servicio
      description: Servicio a comprobar
      required: true
      enforced: true
      value: nginx
      values:
        - nginx
        - php8.3-fpm
    - name: reiniciar
      description: Reiniciar el servicio si no está activo
      required: true
      enforced: true
      value: "no"
      values:
        - "no"
        - "si"
  sequence:
    keepgoing: true
    strategy: node-first
    commands:
      - exec: uptime
      - exec: df -h /
      - exec: free -h
      - exec: systemctl status ${option.servicio} --no-pager --lines=20
      - script: |
          #!/usr/bin/env bash
          set -euo pipefail
          servicio="@option.servicio@"
          if systemctl is-active --quiet "$servicio"; then
            echo "$servicio activo"
          elif [ "@option.reiniciar@" = "si" ]; then
            sudo systemctl restart "$servicio"
            systemctl is-active "$servicio"
          else
            echo "$servicio NO activo, reinicio no solicitado"
            exit 1
          fi

En los comandos exec las opciones se referencian como ${option.nombre} y dentro de scripts como @option.nombre@.

Para que el usuario deploy pueda reiniciar solo esos servicios, crea en cada nodo una regla de sudo limitada:

sudo visudo -f /etc/sudoers.d/rundeck-deploy
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php8.3-fpm

Importa el job en Jobs > Job Actions > Upload Definition, elige el archivo y el formato YAML. Ejecútalo con Run Job Now: verás un bloque de salida por nodo y el estado final de cada paso. Todas las ejecuciones quedan en Activity con usuario, hora y log completo, lo que sirve después para el informe del incidente.

Lanzar el runbook desde una alerta

Para que tu sistema de monitorización lance el runbook, crea un webhook en Webhooks > Create Webhook, elige el plugin Run Job, selecciona el job y fija las opciones, por ejemplo -servicio nginx -reiniciar no. Rundeck muestra la URL del webhook, que puedes invocar con un POST:

curl -X POST "https://rundeck.your_domain/api/45/webhook/your_webhook_token#runbook-web"

En Activity debe aparecer una nueva ejecución del runbook lanzada por el webhook. Trata esa URL como un secreto: cualquiera que la conozca puede lanzar el job.

Paso 9: Limitar permisos con una política ACL

El usuario operador1 pertenece al grupo operadores, que aún no tiene permisos. Las políticas ACL son archivos .aclpolicy en /etc/rundeck/ y Rundeck los recarga sin reiniciar. Crea una política que permita ver y ejecutar jobs, pero no crearlos ni editarlos:

sudo nano /etc/rundeck/operadores.aclpolicy
description: Operadores, ver y ejecutar jobs en todos los proyectos
context:
  project: '.*'
for:
  resource:
    - equals:
        kind: event
      allow: [read]
  job:
    - allow: [read, run, kill]
  node:
    - allow: [read, run]
by:
  group: operadores

---

description: Operadores, acceso de lectura a nivel de aplicación
context:
  application: 'rundeck'
for:
  resource:
    - equals:
        kind: system
      allow: [read]
  project:
    - match:
        name: '.*'
      allow: [read]
  storage:
    - allow: [read]
by:
  group: operadores
sudo chown rundeck:rundeck /etc/rundeck/operadores.aclpolicy
sudo chmod 640 /etc/rundeck/operadores.aclpolicy

Inicia sesión como operador1 en una ventana privada: debe ver el proyecto y poder pulsar Run Job Now, pero no el botón de crear jobs ni la configuración del proyecto. Si una política tiene errores de sintaxis, aparece marcada en System > Access Control.

Solución de problemas

El servicio no arranca. Revisa el log de arranque, donde suelen aparecer errores de conexión a PostgreSQL o de versión de Java:

sudo journalctl -u rundeckd -n 50 --no-pager
sudo tail -n 100 /var/log/rundeck/service.log

Error Authentication failure o Host key verification failed al ejecutar en un nodo. Comprueba que la ruta ssh-key-storage-path del YAML coincide con la del almacén de claves y que la conexión manual del paso 7 funciona como usuario rundeck.

Los jobs programados se ejecutan a una hora distinta. Rundeck usa la zona horaria del sistema. Compruébala con timedatectl, ajústala con sudo timedatectl set-timezone Europe/Madrid y reinicia rundeckd.

Conclusión

Tienes Rundeck funcionando en Ubuntu 24.04 con PostgreSQL, HTTPS, un inventario de nodos por SSH, un runbook de incidentes que se puede lanzar a mano o desde un webhook y un rol de operador con permisos limitados. Como siguientes pasos, puedes añadir un calendario al job desde la pestaña Schedule, integrar el webhook con tu herramienta de alertas y configurar copias de seguridad de la base de datos rundeck con pg_dump.