SaltStack on Your VPS Series
    Part 1 of 6

    Installation & Master/Minion Architecture

    Full install walkthrough for Ubuntu 22.04, master/minion config, key management, firewall rules, and your first remote commands.

    30 minutes
    2+ RamNode VPS instances
    Prerequisites

    2+ RamNode VPS, Ubuntu 22.04, SSH access

    Time to Complete

    25–30 minutes

    Recommended Plan

    Master: 1GB+ ($6/mo), Minions: 512MB+

    Looking for Ansible instead? Check out our standalone Ansible Deployment Guide.

    What SaltStack Is

    SaltStack (often just called "Salt") is an open-source configuration management and remote execution tool written in Python. It uses a persistent message bus (ZeroMQ or TCP) between a central master and managed minions, making it extremely fast at scale — executing a command across 1,000 nodes takes roughly the same time as executing it across 10.

    Salt does three things well:

    • Remote execution — run commands or scripts on any set of servers simultaneously
    • Configuration management — define the desired state of a server and enforce it
    • Orchestration — coordinate multi-step deployments across multiple servers in sequence

    Architecture Overview

    The Salt Master is your control node — it holds state files, configuration, and keys. Salt Minions are the servers you manage. Each minion runs a lightweight daemon that connects back to the master. Communication happens over ports 4505 (publish) and 4506 (return).

    For small environments (under 50 minions), a single $6–12/month VPS works fine as your master. For larger fleets, a dedicated server with more RAM is worthwhile.

    Server Requirements

    Salt Master

    • • Ubuntu 22.04 or 24.04 LTS
    • • 1 vCPU min, 2+ recommended
    • • 1GB RAM min, 2GB+ for 20+ minions
    • • Ports 4505 and 4506 open inbound

    Salt Minions

    • • Any supported Linux distribution
    • • 512MB RAM sufficient for the daemon
    • • Outbound access to master on 4505/4506

    Installing the Salt Master

    Add the Salt Repository

    Add Salt repo (master)
    # Import the Salt Project GPG key
    curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public | sudo tee /usr/share/keyrings/salt-archive-keyring.pgp > /dev/null
    
    # Add the repository (Ubuntu 22.04 / Jammy)
    echo "deb [signed-by=/usr/share/keyrings/salt-archive-keyring.pgp arch=amd64] https://packages.broadcom.com/artifactory/saltproject-deb/ stable main" | sudo tee /etc/apt/sources.list.d/salt.list
    
    sudo apt update

    Install and Configure

    sudo apt install salt-master -y

    Edit the master config at /etc/salt/master:

    /etc/salt/master
    # The interface the master binds to
    interface: 0.0.0.0
    
    # Where Salt looks for state files
    file_roots:
      base:
        - /srv/salt
    
    # Where pillars (secret/variable data) live
    pillar_roots:
      base:
        - /srv/pillar
    
    # Log level
    log_level: info
    sudo mkdir -p /srv/salt /srv/pillar
    sudo systemctl enable salt-master
    sudo systemctl start salt-master
    sudo systemctl status salt-master

    Firewall Rules

    sudo ufw allow 4505/tcp
    sudo ufw allow 4506/tcp
    sudo ufw reload

    Installing Salt Minions

    Run these steps on each server you want to manage:

    Add Salt repo and install (minion)
    curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public | sudo tee /usr/share/keyrings/salt-archive-keyring.pgp > /dev/null
    
    echo "deb [signed-by=/usr/share/keyrings/salt-archive-keyring.pgp arch=amd64] https://packages.broadcom.com/artifactory/saltproject-deb/ stable main" | sudo tee /etc/apt/sources.list.d/salt.list
    
    sudo apt update
    sudo apt install salt-minion -y

    Configure the minion at /etc/salt/minion:

    /etc/salt/minion
    # Point the minion at your master
    master: your.master.ip.or.hostname
    
    # Give this minion a human-readable ID
    id: web-01
    sudo systemctl enable salt-minion
    sudo systemctl start salt-minion

    Accepting Minion Keys

    Salt uses public key cryptography to authenticate minions. On the master, check pending keys:

    sudo salt-key -L
    Accepted Keys:
    Denied Keys:
    Unaccepted Keys:
    web-01
    Rejected Keys:
    # Accept a specific key
    sudo salt-key -a web-01
    
    # Accept all pending keys (use with caution)
    sudo salt-key -A
    
    # Verify connectivity
    sudo salt 'web-01' test.ping
    web-01:
        True

    First Remote Execution Commands

    The syntax is: salt '<target>' <module>.<function> [arguments]

    # Ping all minions
    sudo salt '*' test.ping
    
    # Get OS info
    sudo salt '*' grains.item os osrelease
    
    # Run a shell command
    sudo salt '*' cmd.run 'uptime'
    
    # Check disk usage
    sudo salt '*' disk.usage
    
    # Install a package
    sudo salt 'web-01' pkg.install nginx
    
    # Check a service status
    sudo salt 'web-01' service.status nginx

    Targeting Minions

    # Exact match
    salt 'web-01' test.ping
    
    # Glob
    salt 'web-*' test.ping
    
    # List
    salt -L 'web-01,web-02,db-01' test.ping
    
    # By grain (built-in system attribute)
    salt -G 'os:Ubuntu' test.ping
    
    # By regex
    salt -E 'web-[0-9]+' test.ping

    The Salt CLI Tools

    CommandPurpose
    saltRun commands against minions from the master
    salt-callRun Salt commands locally on a minion
    salt-keyManage minion key acceptance
    salt-runRun Salt runners (master-side jobs)
    salt-cpCopy files from master to minions
    # salt-call is handy for testing states locally
    sudo salt-call --local test.ping
    
    # Check all grains on the local minion
    sudo salt-call --local grains.items

    Troubleshooting Connection Issues

    If salt '*' test.ping returns nothing or hangs:

    On the minion:

    # Check if the minion daemon is running
    sudo systemctl status salt-minion
    
    # Check minion logs for connection errors
    sudo tail -f /var/log/salt/minion
    
    # Verify the master address is correct
    grep master /etc/salt/minion
    
    # Test network connectivity to master ports
    nc -zv your.master.ip 4505
    nc -zv your.master.ip 4506

    On the master:

    # Confirm the key is in Accepted Keys
    sudo salt-key -L
    
    # Check master logs
    sudo tail -f /var/log/salt/master
    
    # Verify master is listening
    ss -tlnp | grep salt

    Common Issues

    • • Firewall blocking ports 4505/4506 on the master
    • • Minion's master config pointing to wrong IP
    • • Key not yet accepted (shows in Unaccepted Keys)
    • • Clock skew between master and minion (NTP sync required)

    What's Next

    You now have a working Salt master with connected minions and can run arbitrary commands across your fleet. In Part 2, we move from imperative remote execution to declarative configuration management — writing state files that describe what a server should look like.