Comprehensive SaltStack Guide: Commands, Configuration, and Advanced Features

Core Commands

salt - Primary command for executing modules on minions from the master:

salt [options] '<target>' <function> [arguments]

Example: salt '*' test.ping

salt-run - Execute runnner modules on the master:

salt-run manage.status    # View all minion statuses
salt-run manage.down      # Show offline minions
salt-run manage.up        # Show online minions

salt-key - Manage authentication keys:

salt-key -L                   # List all minion keys
salt-key -a <minion-id>      # Accept specific key
salt-key -d <minion-id>      # Delete specific key
salt-key -A                   # Accept all pending keys
salt-key -D                   # Delete all keys

salt-call - Execute modules locally on minion:

salt-call test.ping           # Local ping test
salt-call cmd.run 'ifconfig'  # Execute command locally

salt-cp - Distribute files to minions:

salt-cp '*' source.txt /tmp/destination.txt

User Execution Permissions

Access Control Lists (ACL)

Configure in master configuration file:

client_acl:
  monitor:
    - 'test*':
    - 'test.*'
  dev:
    - 'service.*'
  sa:
    - '.*'

After configuration, restart master and set proper permissions:

chmod +r /etc/salt/master
chmod +x /var/run/salt
chmod +x /var/cache/salt

External Authentication

Configure in master:

external_auth:
  pam:
    monitor:
      - 'test':
        - test.
    sa:
      - .*

Use tokens to avoid repeated password prompts:

salt -T -a pam '*' test.ping

Targeting Minions

Targeting Methods

Globbing (default):

salt 'web*' test.ping

Regular Expressions:

salt -E 'web1-(prod|dev)' test.ping

List:

salt -L 'server1,server2,server3' test.ping

Grains:

salt -G 'os:CentOS' test.ping
salt '*' grains.items             # View all grains
salt '*' grains.ls                # List grain keys
salt '*' grains.item num_cpus     # Get specific grain

Node Groups:

Define in master configuration:

nodegroups:
  web_servers: 'L@web1,web2 or web3*'
  db_servers: 'G@os:CentOS and db*'

Usage:

salt -N web_servers test.ping

Compound Targeting:

salt -C 'G@os:CentOS and L@192.168.1.10,192.168.1.11' test.ping

Remote Execution

Basic syntax for remote command execution:

salt '<target>' <function> [arguments]

Examples:

salt '*' service.restart httpd
salt '*' pkg.install vim
salt '*' cmd.run 'uptime'

Multi-Master Configuration

  1. Install Salt Master on additional server
  2. Copy master keys from primary master: ``` scp /etc/salt/pki/master/master.pem newmaster:/etc/salt/pki/master/
  3. Start new master service
  4. Configure minions to connect to multiple masters: ``` master:
    • master1.example.com
    • master2.example.com
  5. Restart minion service
  6. Accept keys on new master

Pillar Data Management

Pillar stores sensitive and minion-specific data on the master.

Viewing Pillar Data

salt '*' pillar.items
salt '*' pillar.item <key>
salt '*' pillar.get <key>:<subkey>

Creating Pillar Data

1. Define pillar roots (default: /srv/pillar):

mkdir /srv/pillar
cd /srv/pillar

2. Create pillar data file:

vim /srv/pillar/apache.sls
apache_version: '2.4.41'
document_root: '/var/www/html'

3. Create top file:

vim /srv/pillar/top.sls
base:
  '*':
    - apache

4. Refresh pillar data:

salt '*' saltutil.refresh_pillar

Grains System

Grains provide static information about minions.

Viewing Grains

salt '*' grains.items
salt '*' grains.item osrelease
salt '*' grains.get fqdn

Custom Grains

Create custom grainss module:

mkdir /srv/salt/_grains
vim /srv/salt/_grains/custom.py
def server_role():
    grains = {}
    grains['server_role'] = 'webserver'
    return grains

Sync to minions:

salt '*' saltutil.sync_grains

State Management

States define the desired configuration of systems.

State File Example

apache:
  pkg.installed:
    - name: httpd
  service.running:
    - name: httpd
    - require:
      - pkg: httpd
    - watch:
      - file: /etc/httpd/conf/httpd.conf

/etc/httpd/conf/httpd.conf:
  file.managed:
    - source: salt://apache/httpd.conf
    - user: root
    - group: root
    - mode: 644

Top File Configuration

base:
  '*':
    - apache
  'web*':
    - webserver
    - database

Executing States

salt '*' state.sls apache
salt '*' state.highstate

Rendering Systems

Salt supports multiple renderers for state files.

Jinja Templates

apache:
  pkg.installed:
    {% if grains['os'] == 'RedHat' %}
    - name: httpd
    {% elif grains['os'] == 'Ubuntu' %}
    - name: apache2
    {% endif %}
  service.running:
    - name: httpd
    {% if grains['os'] == 'RedHat' %}
    - name: httpd
    {% else %}
    - name: apache2
    {% endif %}

Python Renderer

#!py
def run():
    config = {}
    if grains['os_family'] == 'RedHat':
        config['httpd'] = {
            'pkg': ['installed'],
            'service': ['running']
        }
    return config

Requisite System

Define dependencies between states.

Require/Require In

/etc/httpd/conf/httpd.conf:
  file.managed:
    - source: salt://apache/httpd.conf
    - require_in:
      - service: httpd

httpd:
  service.running:
    - require:
      - pkg: httpd

Watch/Watch In

httpd:
  service.running:
    - watch:
      - file: /etc/httpd/conf/httpd.conf

/etc/httpd/conf/httpd.conf:
  file.managed:
    - source: salt://apache/httpd.conf
    - watch_in:
      - service: httpd

Environment Management

Configure multiple environments in master:

file_roots:
  base:
    - /srv/salt/prod
  dev:
    - /srv/salt/dev
    - /srv/salt/prod
  test:
    - /srv/salt/test
    - /srv/salt/prod

Scheduled Tasks

Master Schedules

schedule:
  overstate:
    function: state.over
    minutes: 30
    hours: 2

Minion Schedules

schedule:
  highstate:
    function: state.highstate
    minutes: 60
  backup:
    function: cmd.run
    args:
      - rsync -av /data/ backup@server:/backup/
    hours: 6

Event System and Reacotrs

Reactors Configuration

Configure in master:

reactor:
  - 'salt/minion/*/start':
    - /srv/reactor/start.sls
  - 'custom/event/*':
    - /srv/reactor/custom.sls

Reactor Example

{% if data['id'] == 'web01' %}
apply_config:
  local.state.apply:
    - tgt: {{ data['id'] }}
    - arg:
      - webserver
{% endif %}

Salt Mine

Mine gathers and stores data from minions for sharing.

Configuration

Configure in minion:

mine_functions:
  network.interfaces: []
  disk.usage: []
mine_interval: 60

Usage

salt '*' mine_get '*' network.interfaces
salt 'web01' mine_get 'db*' disk.usage

Salt SSH

Agentless Salt execution via SSH.

Roster Configuration

web01:
  host: 192.168.1.10
  user: root
  passwd: password
  port: 22
  sudo: True

web02:
  host: 192.168.1.11
  user: deploy
  priv: /path/to/private/key
  sudo: True

Usage

salt-ssh '*' test.ping
salt-ssh '*' -r 'ls -l /tmp'
salt-ssh '*' state.sls apache

Returners

Direct minion return data to various storage systems.

Custom Returner Example

def __virtual__():
    return 'custom_log'

def returner(ret):
    import json
    with open('/var/log/salt/returns.log', 'a') as f:
        f.write(json.dumps(ret) + '\n')

Usage

salt '*' test.ping --return custom_log

Extending SaltStack

Custom Execution Module

def custom_function(param):
    """
    Custom function example
    """
    cmd = 'custom_command --option {0}'.format(param)
    return __salt__['cmd.run'](cmd)

Custom State Module

def managed(name, source=None):
    ret = {'name': name,
           'changes': {},
           'result': False,
           'comment': '',
           'duration': ''}
    
    if source:
        # File management logic here
        ret['result'] = True
        ret['comment'] = 'File managed successfully'
    
    return ret

Job Management

Viewing Active Jobs

salt-run jobs.active
salt '*' saltutil.running

Job Lookup

salt '*' test.ping -v  # Show JID
salt-run jobs.lookup_jid <jid>

Terminating Jobs

salt '*' saltutil.term_job <jid>
salt '*' saltutil.kill_job <jid>

File Backup and Restore

Configuration

/tmp/test.conf:
  file.managed:
    - source: salt://files/test.conf
    - backup: minion

Managing Backups

salt '*' file.list_backups /tmp/test.conf
salt '*' file.restore_backup /tmp/test.conf <backup_id>
salt '*' file.delete_backup /tmp/test.conf <backup_id>

Master Configuration Options

interface: 0.0.0.0
publish_port: 4505
ret_port: 4506
user: root
timeout: 5
keep_jobs: 24
job_cache: True
file_roots:
  base:
    - /srv/salt
pillar_roots:
  base:
    - /srv/pillar
log_level: warning

Minion Configuration Options

master: salt.example.com
master_port: 4506
id: minion01
user: root
cache_jobs: False
backup_mode: minion
renderer: yaml_jinja
log_level: info
tcp_keepalive: True

Tags: SaltStack Configuration Management remote execution automation devops

Posted on Mon, 25 May 2026 19:51:23 +0000 by lalloo