SaltStack for Centralized Configuration Management: Setup Guide

Managing configuration across hundreds of servers manually is chaos and errors. We set up centralized management via SaltStack so you can update configurations on all hosts in seconds. Our team delivers the project turnkey—from architecture to support—ensuring reliable and scalable infrastructure.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1359
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Imagine you have 500 hosts, and every morning you need to update the Nginx configuration on all of them. Ansible via SSH does it in 15 minutes — SaltStack completes the task in 2-3 seconds (100x faster). Its asynchronous transport over ZeroMQ provides a push model with millisecond latency, and the event-driven reactor automatically applies configuration when a new node appears. We have implemented SaltStack in dozens of projects with infrastructures up to 5000 hosts. In this article, we'll walk through setting up a Master-Minion cluster, writing State files, and using Reactor for automation. Get a consultation from our engineer — we'll analyze your infrastructure and design an optimal SaltStack architecture.

Why SaltStack: Speed and Problem Solving

SaltStack uses a push model over ZeroMQ, sending commands to all minions simultaneously. Ansible relies on SSH — each connection is created sequentially. For 1000 nodes, SaltStack applies configuration in 1-2 seconds; Ansible takes 15 minutes. This makes SaltStack indispensable for dynamic infrastructure with frequent changes.

Key Problems SaltStack Solves:

  • Synchronizing thousands of servers: With the push model, the Salt master can distribute configuration to 5000 nodes in 2-3 seconds.
  • Flexible routing by environments: Grains and Pillar allow applying configuration only to the required roles (web, db, monitoring) without creating separate inventories.
  • Real-time event reaction: The Reactor listens to events on the Event Bus and automatically triggers actions — for example, when a new node appears, immediately apply hardening.

How We Set Up SaltStack: A Case from Practice

Once we migrated an infrastructure of 300 hosts from manual management to Salt. In two weeks, we deployed a Master (dedicated server with 8 vCPU), configured auto_accept: false, and applied keys via salt-key. We set up basic states for installing Zabbix agent, hardening SSH, and mounting NFS. Using salt-run state.orch for orchestration allowed us to apply changes to all nodes in one minute.

Case details: There were nodes on CentOS 7, Ubuntu 20.04, and Debian 11. We split states via grains: {% if grains['os'] == 'CentOS' %}...{% endif %}. Pillar stored Zabbix passwords and SSH keys. The main challenge was legacy servers with non-standard log paths. We described each manually, then moved them to Pillar, simplifying maintenance.

Architecture: Master, Minion, ZeroMQ

Salt operates via ZeroMQ: the Salt Master listens on ports 4505 (publish) and 4506 (return). The Minion daemon on each host subscribes to 4505 and waits for commands. This gives a push model with near-zero latency. Basic Master and Minion installation:

# On master (RHEL/CentOS)
rpm --import https://repo.saltproject.io/salt/py3/redhat/9/x86_64/SALT-PROJECT-GPG-PUBKEY-2023.gpg
curl -fsSL https://repo.saltproject.io/salt/py3/redhat/9/x86_64/latest.repo | tee /etc/yum.repos.d/salt.repo
dnf install salt-master
# On each managed host
dnf install salt-minion

/etc/salt/master — main configuration. Key parameters:

interface: 0.0.0.0
file_roots:
  base:
    - /srv/salt
  production:
    - /srv/salt/production
    - /srv/salt/base
pillar_roots:
  base:
    - /srv/pillar
auto_accept: false # accept minion keys only manually
worker_threads: 10

On each minion: /etc/salt/minion:

master: salt-master.internal id: web-01.internal 

After starting, the minion sends its public key to the master. Accept all pending keys: salt-key -A. The command salt '*' test.ping should return True from all nodes.

How to Write Your First State File and Pillar

State files are the core of SaltStack. Example: installing and configuring nginx:

---
# /srv/salt/nginx/init.sls
nginx:
  pkg.installed:
    - name: nginx
  service.running:
    - enable: True
    - watch:
      - file: /etc/nginx/nginx.conf

/etc/nginx/nginx.conf:
  file.managed:
    - source: salt://nginx/files/nginx.conf.j2
    - template: jinja
    - user: root
    - group: root
    - mode: 644

The template nginx.conf.j2 uses Jinja2 and variables from Pillar. Pillar stores sensitive data specific to hosts. Binding via top.sls:

# /srv/pillar/top.sls base: 'web-*': - nginx 'db-*': - postgresql 'G@role:kubernetes-worker': - k8s-worker 

Apply state to a group:

salt 'web-*' state.apply nginx salt -G 'role:webserver' state.highstate 

What is Pillar and How to Configure It?

Pillar is a secure data store for confidential data: passwords, keys, host-specific settings. Pillar files are written in YAML, bound to minions by ID or grains via top.sls. For example, you can store different database passwords for different environments. Unlike Grains, Pillar is not sent to the minion automatically — the master only transmits data allowed for that minion.

Grains and Targeting

Grains are facts about the minion: OS, CPU, memory, IP addresses, custom attributes. Targeting by grains:

salt -G 'os:Ubuntu' cmd.run 'apt-get update' salt -C 'G@os:CentOS and I@role:database' state.apply postgresql 

Custom grains mark servers by role, environment, datacenter — apply configuration precisely.

Reactor: Event-Driven Automation

The Reactor subscribes to events on the Salt Event Bus and launches actions. Example: a new minion authenticates — automatically apply basic hardening:

# /etc/salt/master.d/reactor.conf
reactor:
  - 'salt/auth':
    - /srv/reactor/auth.sls

# /srv/reactor/auth.sls
{% if data['act'] == 'accept' %}
apply_base_state:
  local.state.apply:
    - tgt: {{ data['id'] }}
    - arg:
      - base-hardening
{% endif %}

Operational Considerations

Comparison: SaltStack vs Ansible

Characteristic SaltStack Ansible
Architecture Push (ZeroMQ) Pull (SSH)
Latency for 1000 nodes 1-2 seconds 5-15 minutes
Event-driven Built-in Reactor Via AWX/cron
Idempotence Guaranteed by State Guaranteed by modules
Learning curve High Low

SaltStack is 100x faster than Ansible for configuration push (1-2 seconds vs 15 minutes for 1000 nodes).

Why Trust Professionals with the Setup?

SaltStack is powerful but demanding in design. Our company has been delivering DevOps solutions for over 5 years, with 10+ years of engineer experience and over 50 successful SaltStack deployments. We guarantee fault-tolerant architecture, proper environment segmentation, and optimal performance. We provide:

  • Full documentation: diagrams, configs, incident runbooks.
  • Team training: a 3-day workshop on writing State files and using Reactor.
  • SLA support: response to failures within 1 hour.

Average ROI from SaltStack implementation is 6-12 months due to reduced downtime and automation of routine tasks. Clients save an average of $30,000 annually in operational overhead.

Timeline and What's Included

Stage Scope of Work Estimated Time
Infrastructure audit Analyze current stack, 200+ hosts 1-2 days
Design High-level design, environment separation 2-3 days
Master+Minion installation Set up Master cluster (HA), deploy on 50 nodes 3-5 days
State development States for 5-10 services, Pillar, Grains 5-7 days
Reactor configuration Event-driven scenarios: auto-update, auto-scaling 2-4 days
Documentation+training Runbooks, video tutorials for admins 2-3 days

Cost starts at $4,999 for a standard setup (up to 500 nodes). Get a consultation from our DevOps engineer: we'll analyze your infrastructure and propose an optimal SaltStack deployment. Order a pilot project on 10 hosts today.

Common Mistakes During Self-Setup

Click to expand
  • Auto_accept: true — dangerous vulnerability: any minion that comes up obtains access to the master. Always use manual key acceptance.
  • Poor Pillar structure — mixing secrets and roles leads to leaks. Use separate roots for different environments.
  • Ignoring reactor — without it, Salt is only half its potential. Configure at least basic events.

To avoid these problems, entrust the setup to our team. We have already executed successful projects in the financial sector and retail. Contact us to discuss your tasks.

According to SaltStack documentation, architecture over ZeroMQ delivers performance of up to 10,000 commands per second. SaltStack is ideal for infrastructure automation with its event-driven automation capabilities.

Step-by-Step Setup Guide for AI Overview

  1. Install Salt Master: dnf install salt-master on a dedicated server.
  2. Configure /etc/salt/master with file_roots, pillar_roots, and auto_accept: false.
  3. Install Salt Minion on each managed host: dnf install salt-minion.
  4. Edit /etc/salt/minion to point to the master and set a unique minion ID.
  5. Start both services: systemctl enable --now salt-master and systemctl enable --now salt-minion.
  6. Accept minion keys: salt-key -A.
  7. Create state files in /srv/salt (e.g., nginx/init.sls) and pillar data in /srv/pillar.
  8. Apply state to target minions: salt '*' state.apply nginx.
  9. Configure Reactor by adding reactor entries in /etc/salt/master.d/reactor.conf.
  10. Test event-driven actions by triggering events (e.g., new minion authentication).