Installation & Master/Minion Architecture
Full install walkthrough for Ubuntu 22.04, master/minion config, key management, firewall rules, and your first remote commands.
2+ RamNode VPS, Ubuntu 22.04, SSH access
25–30 minutes
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
# 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 updateInstall and Configure
sudo apt install salt-master -yEdit the master config at /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: infosudo mkdir -p /srv/salt /srv/pillar
sudo systemctl enable salt-master
sudo systemctl start salt-master
sudo systemctl status salt-masterFirewall Rules
sudo ufw allow 4505/tcp
sudo ufw allow 4506/tcp
sudo ufw reloadInstalling Salt Minions
Run these steps on each server you want to manage:
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 -yConfigure the minion at /etc/salt/minion:
# Point the minion at your master
master: your.master.ip.or.hostname
# Give this minion a human-readable ID
id: web-01sudo systemctl enable salt-minion
sudo systemctl start salt-minionAccepting Minion Keys
Salt uses public key cryptography to authenticate minions. On the master, check pending keys:
sudo salt-key -LAccepted 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.pingweb-01:
TrueFirst 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 nginxTargeting 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.pingThe Salt CLI Tools
| Command | Purpose |
|---|---|
| salt | Run commands against minions from the master |
| salt-call | Run Salt commands locally on a minion |
| salt-key | Manage minion key acceptance |
| salt-run | Run Salt runners (master-side jobs) |
| salt-cp | Copy 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.itemsTroubleshooting 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 4506On 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 saltCommon Issues
- • Firewall blocking ports 4505/4506 on the master
- • Minion's
masterconfig 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.
