agents/docs/architecture.md
Salt is a Python-based configuration management system using a master-minion architecture:
Salt uses a loader system to discover and load different types of modules:
salt/modules/)Functions executed on minions (e.g., pkg.install, file.read). There are 264+ execution modules providing the CLI commands available via Salt.
Examples:
salt/modules/pkg.py - Package management (virtual module)salt/modules/file.py - File operationssalt/modules/cmd.py - Command executionsalt/modules/systemd_service.py - systemd service managementsalt/states/)Declarative configuration management (e.g., pkg.installed, file.managed). There are 126+ state modules providing idempotent configuration.
Examples:
salt/states/pkg.py - Package installation statessalt/states/file.py - File management statessalt/states/service.py - Service management statessalt/runners/)Master-side operations (e.g., salt-run jobs.list_jobs). Runners execute on the Salt master.
salt/wheel/)Master configuration management (key management, config). Used for managing the Salt master itself.
salt/grains/)Static system information collection. Grains provide facts about the minion system (OS, CPU, memory, etc.).
salt/pillar/)Dynamic configuration data backends. Pillars provide secure, targeted data to minions.
salt/beacons/)System monitoring triggers (watch for events). Beacons monitor system events and fire events on the event bus.
salt/engines/)Long-running processes on master or minion. Engines provide persistent functionality.
salt/returners/)Store or send command output to external systems (databases, message queues, etc.).
salt/renderers/)Template engines (Jinja, Mako, YAML, JSON). Renderers process state files.
salt/matchers/)Target matching (glob, pcre, grain, pillar, compound). Matchers determine which minions execute commands.
salt/utils/)Shared utility functions (170+ modules). Utilities provide common functionality across Salt.
salt/
├── master.py, minion.py, state.py # Core daemon implementations
├── loader/ # Plugin loader system (LazyLoader)
├── modules/ # 264+ execution modules
├── states/ # 126+ state modules
├── runners/, wheel/ # Master operations and config
├── beacons/, engines/ # Monitoring triggers, long-running processes
├── grains/, pillar/ # System info, config data backends
├── renderers/, returners/ # Template engines, return data storage
├── matchers/, transport/ # Targeting systems, communication layer
├── utils/ # 170+ utility modules
└── ext/ # Vendored third-party code
tests/
├── pytests/
│ ├── unit/ # Fast tests, no daemons/network
│ ├── functional/ # End-to-end, no external deps
│ ├── integration/ # With daemons/network
│ ├── scenarios/ # Scenario-based testing
│ └── pkg/ # Package install/upgrade tests
└── support/ # Test helpers and fixtures
salt/state.py compiles YAML/Jinja templates into execution chunks. Uses NetworkX for dependency graph management with requisites:
require: Must run afterwatch: Run if watched state changesonchanges: Run only if watched state changesonfail: Run if watched state failslisten: Listen for notificationsprereq: Run before (with test mode check)All state operations are idempotent and support test mode (test=True).
salt/transport/ handles communication between master and minions:
salt/crypt.py)salt/utils/event.py provides ZeroMQ pub/sub with namespaced event tags for real-time communication between all components.
Events are namespaced with tags like:
salt/job/<jid>/new - New job startedsalt/job/<jid>/ret/<minion_id> - Job return from minionsalt/auth - Authentication eventssalt/minion/<minion_id>/start - Minion startedThe loader system (salt/loader/) dynamically discovers and loads modules at runtime. Key features:
__virtual__()__salt__, __opts__, __grains__, etc.Salt is transitioning from Tornado coroutines to native asyncio:
async/await syntax, not @tornado.gen.coroutineSalt includes a file server that serves files to minions:
salt:// URLs reference files on the file serverMinions can be targeted in multiple ways:
*, web*.example.comos:Ubuntu, kernel:Linuxrole:webserverG@os:Ubuntu and webserver*web1,web2,web3Modules only load on first access. Import-time side effects may not occur until first use of a module function.
Use __context__ to cache expensive operations within a Salt run (single execution).
__init__.pysalt/modules/pkg.py → pkg.*__virtualname__ for different name than filenamedoc/topics/development/modules/developing.rstdoc/ref/states/writing.rstCONTRIBUTING.rstsalt/modules/test.pysalt/modules/file.pysalt/modules/aptpkg.py, salt/modules/yumpkg.pysalt/modules/systemd_service.pysalt/states/pkg.pysalt/states/file.py