--- title: "Cómo instalar SaltStack en Ubuntu 24.04 (master y minion)" description: "Instala Salt master y minion en Ubuntu 24.04 desde el repositorio oficial, acepta las claves, ejecuta comandos remotos y aplica un state con datos de pillar." category: "Automatización e IaC" language: es source: https://cubepath.com/es/docs/automatización-e-iac/instalacion-y-configuracion-de-saltstack updated: 2026-09-25 --- # Cómo instalar SaltStack en Ubuntu 24.04 (master y minion) Salt (SaltStack) es una herramienta de gestión de configuración y ejecución remota con arquitectura master/minion: un servidor central (el master) envía órdenes y estados a los agentes (los minions) a través de un bus de mensajes muy rápido. En este tutorial instalarás un Salt master y un minion en Ubuntu 24.04 desde el repositorio oficial del proyecto, aceptarás la clave del minion, ejecutarás comandos remotos y aplicarás un state que instala y configura Nginx usando datos de pillar. ## Requisitos previos Necesitas: - Dos servidores con Ubuntu 24.04 LTS, por ejemplo dos VPS de CubePath: uno hará de master y otro de minion. Con 1 GB de RAM por servidor es suficiente para este tutorial. - Un usuario no root con privilegios `sudo` en ambos. - Conectividad privada o pública entre ellos. El minion debe poder llegar al master por los puertos TCP **4505** y **4506**. En la guía se usan estos valores de ejemplo; sustitúyelos por los tuyos: | Rol | Hostname | IP | |-----|----------|----| | Master | `salt-master` | `master_ip` | | Minion | `web01` | `minion_ip` | ## Paso 1: Añadir el repositorio oficial de Salt Los paquetes de Salt que trae Ubuntu están desactualizados. El proyecto Salt publica sus paquetes (compilación "onedir", con su propio Python) en un repositorio de Broadcom. Repite este paso en **los dos servidores**. Crea el directorio de claves y descarga la clave pública del repositorio: ```bash sudo mkdir -m 755 -p /etc/apt/keyrings curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public | sudo tee /etc/apt/keyrings/salt-archive-keyring.pgp > /dev/null ``` Descarga la definición del repositorio que mantiene el proyecto: ```bash curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources | sudo tee /etc/apt/sources.list.d/salt.sources ``` La salida muestra el contenido del archivo, que apunta a `packages.broadcom.com` y usa la clave que acabas de descargar en `Signed-By`. Actualiza el índice y comprueba que los paquetes vienen de ese repositorio: ```bash sudo apt update apt-cache policy salt-master ``` ```output salt-master: Installed: (none) Candidate: Version table: 500 500 https://packages.broadcom.com/artifactory/saltproject-deb stable/main amd64 Packages ``` La versión concreta cambiará con el tiempo; lo importante es que el origen sea `packages.broadcom.com`. > Nota: el repositorio contiene varias ramas (LTS y STS) y apt instala la más reciente. Si quieres quedarte en una rama concreta, fíjala con un archivo en `/etc/apt/preferences.d/` antes de instalar, tal como indica la guía de instalación oficial de Salt. Master y minion deben usar la misma versión o el master una más nueva. ## Paso 2: Instalar y configurar el master En el servidor **master**, instala el paquete: ```bash sudo apt install salt-master ``` Crea los directorios donde vivirán los states y los datos de pillar. `/srv/salt` y `/srv/pillar` son las rutas por defecto de `file_roots` y `pillar_roots`, así que no hace falta tocar `/etc/salt/master`: ```bash sudo mkdir -p /srv/salt /srv/pillar ``` Habilita e inicia el servicio: ```bash sudo systemctl enable --now salt-master sudo systemctl status salt-master ``` ```output ● salt-master.service - The Salt Master Server Loaded: loaded (/usr/lib/systemd/system/salt-master.service; enabled; preset: enabled) Active: active (running) since ... ``` Comprueba que escucha en los dos puertos que usa Salt (4505 para publicar órdenes y 4506 para recibir respuestas): ```bash sudo ss -tlnp | grep -E '4505|4506' ``` Si usas UFW, permite esos puertos solo desde la IP del minion: ```bash sudo ufw allow from minion_ip to any port 4505:4506 proto tcp ``` Para terminar este paso, anota la huella de la clave pública del master. La usarás en el minion para verificar que se conecta al master correcto: ```bash sudo salt-key -F master ``` ```output Local Keys: master.pem: ... master.pub: 4d:1a:9c:... ``` ## Paso 3: Instalar y configurar el minion En el servidor **minion**, instala el paquete: ```bash sudo apt install salt-minion ``` El paquete arranca el servicio al instalarse, pero todavía no sabe dónde está el master. En lugar de editar `/etc/salt/minion`, crea un archivo propio en el directorio `minion.d`, que Salt lee automáticamente: ```bash sudo nano /etc/salt/minion.d/master.conf ``` ```yaml master: master_ip master_finger: '4d:1a:9c:...' ``` `master_finger` es la huella de `master.pub` que anotaste en el paso anterior; con ella el minion rechaza cualquier master cuya clave no coincida. Fija el ID del minion. Por defecto Salt usa el hostname, pero escribirlo explícitamente evita que la clave se registre con un nombre inesperado: ```bash echo "web01" | sudo tee /etc/salt/minion_id ``` Reinicia el servicio para que lea la nueva configuración: ```bash sudo systemctl restart salt-minion sudo systemctl enable salt-minion ``` Revisa el registro. Es normal ver que el minion espera a que el master acepte su clave: ```bash sudo journalctl -u salt-minion -n 20 --no-pager ``` ## Paso 4: Aceptar la clave del minion Salt autentica cada minion con un par de claves. El master no confía en un minion hasta que aceptas su clave. En el **master**, lista las claves: ```bash sudo salt-key -L ``` ```output Accepted Keys: Denied Keys: Unaccepted Keys: web01 Rejected Keys: ``` Antes de aceptarla, compara las huellas. En el master: ```bash sudo salt-key -f web01 ``` Y en el minion: ```bash sudo salt-call --local key.finger ``` Si las dos huellas coinciden, acepta la clave en el master: ```bash sudo salt-key -a web01 ``` Confirma con `y`. Ahora prueba la comunicación: ```bash sudo salt 'web01' test.ping ``` ```output web01: True ``` ## Paso 5: Ejecutar comandos remotos Con la clave aceptada ya puedes lanzar módulos de ejecución desde el master. El primer argumento es el objetivo (`'*'` son todos los minions) y después va la función: ```bash sudo salt '*' cmd.run 'uptime' sudo salt '*' grains.item os osrelease sudo salt '*' pkg.version openssl ``` ```output web01: ---------- os: Ubuntu osrelease: 24.04 ``` Los grains son datos que cada minion reporta sobre sí mismo (SO, CPU, red). Puedes usarlos para apuntar a grupos de máquinas, por ejemplo solo a los minions Ubuntu: ```bash sudo salt -G 'os:Ubuntu' test.ping ``` ## Paso 6: Escribir tu primer state Los comandos remotos son útiles, pero la gestión de configuración se hace con states: archivos `.sls` en YAML que describen el estado deseado y que Salt aplica de forma idempotente. En el master, crea un state que instale Nginx, publique una página y mantenga el servicio en marcha: ```bash sudo mkdir -p /srv/salt/nginx sudo nano /srv/salt/nginx/init.sls ``` ```yaml nginx: pkg.installed: [] service.running: - enable: True - require: - pkg: nginx /var/www/html/index.html: file.managed: - source: salt://nginx/files/index.html.jinja - template: jinja - user: root - group: root - mode: '0644' - require: - pkg: nginx ``` Crea la plantilla de la página. Salt la renderiza con Jinja en el minion, así que puede usar grains y pillar: ```bash sudo mkdir -p /srv/salt/nginx/files sudo nano /srv/salt/nginx/files/index.html.jinja ``` ```html

{{ salt['pillar.get']('web:site_name', 'Sitio sin nombre') }}

Servidor: {{ grains['id'] }} ({{ grains['osfinger'] }})

``` Ahora el top file, que decide qué states recibe cada minion: ```bash sudo nano /srv/salt/top.sls ``` ```yaml base: 'web*': - nginx ``` ## Paso 7: Añadir datos con pillar Pillar guarda datos por minion (nombres, puertos, credenciales) en el master y solo los envía a los minions a los que van destinados. Crea el archivo de datos: ```bash sudo nano /srv/pillar/web.sls ``` ```yaml web: site_name: Mi web gestionada con Salt ``` Y el top file de pillar, con la misma sintaxis que el de states: ```bash sudo nano /srv/pillar/top.sls ``` ```yaml base: 'web*': - web ``` Refresca el pillar en los minions y comprueba que el dato llega: ```bash sudo salt '*' saltutil.refresh_pillar sudo salt 'web01' pillar.get web:site_name ``` ```output web01: Mi web gestionada con Salt ``` ## Paso 8: Aplicar el state Antes de cambiar nada, haz una ejecución en seco con `test=True`. Salt muestra lo que cambiaría sin aplicarlo: ```bash sudo salt 'web01' state.apply test=True ``` Si el resultado es el esperado, aplícalo de verdad. Sin argumentos, `state.apply` ejecuta el "highstate", es decir, todo lo que el top file asigna al minion: ```bash sudo salt 'web01' state.apply ``` ```output Summary for web01 ------------ Succeeded: 3 (changed=3) Failed: 0 ------------ Total states run: 3 ``` Compruébalo desde el propio minion (o desde el master con `curl http://minion_ip`): ```bash sudo salt 'web01' cmd.run 'curl -s http://localhost' ``` ```output web01:

Mi web gestionada con Salt

Servidor: web01 (Ubuntu-24.04)

``` Si vuelves a ejecutar `state.apply`, verás `changed=0`: el estado ya coincide con lo declarado. Esa idempotencia es lo que permite aplicar los states de forma periódica sin miedo. ## Solución de problemas - **`Minion did not return. [No response]`**: el minion está caído o no llega al master. Revisa `sudo journalctl -u salt-minion` en el minion y comprueba con `nc -zv master_ip 4506` que el puerto está abierto. - **La clave no aparece en `salt-key -L`**: el minion no apunta al master correcto. Revisa `/etc/salt/minion.d/master.conf` y reinicia `salt-minion`. - **El minion cambió de hostname o se reinstaló**: el master rechazará la clave nueva con el mismo ID. Borra la antigua con `sudo salt-key -d web01` y acepta la nueva. - **`No Top file or master_tops data matches found`**: el patrón del top file no coincide con el ID del minion. Compruébalo con `sudo salt 'web*' test.ping`. - **Errores de renderizado en un `.sls`**: casi siempre son de indentación YAML. Muestra el resultado renderizado con `sudo salt 'web01' state.show_sls nginx`. ## Conclusión Tienes un Salt master que controla un minion con autenticación por claves, ejecuta comandos remotos y aplica un state idempotente alimentado con datos de pillar. Como siguientes pasos, puedes guardar `/srv/salt` y `/srv/pillar` en un repositorio Git, cifrar los secretos de pillar con el renderer GPG de Salt y programar la aplicación periódica del highstate con el scheduler de Salt.