salt Documentation

Software to automate the management and configuration of infrastructure and applications at scale.

RAW Doc

Technical Documentation: saltstack/salt

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`agents/README.md`)

AI Agent Instructions for Salt Development

This directory contains instruction files for various AI coding assistants to help them better understand and work with the Salt codebase.

Purpose

These files provide AI agents with:

  • Salt's architecture and design patterns
  • Coding conventions and best practices
  • Testing guidelines and requirements
  • Common pitfalls to avoid

Available Instructions

  • CLAUDE.md - Instructions for Anthropic's Claude (Claude Code, Claude.ai, etc.)
  • GEMINI.md - Instructions for Google's Gemini
  • CURSOR.md - Instructions for Cursor IDE
  • COPILOT.md - Instructions for GitHub Copilot

Each instruction file provides a quick reference and links to detailed documentation (see below).

Detailed Documentation

The docs/ directory contains comprehensive guides that are referenced by all agent instruction files. This provides a single source of truth for detailed information:

  • development-setup.md - Complete virtual environment setup

    • venv310 and venv312 setup instructions
    • Platform-specific dependencies
    • Installation verification steps
    • Common troubleshooting
  • architecture.md - Salt architecture deep dive

    • Master-minion architecture
    • All module types (execution, state, grains, pillar, beacon, engine, etc.)
    • Directory structure
    • Key components (state compiler, transport layer, event bus, loader system)
  • module-templates.md - Complete code templates

    • Full execution module template with all patterns
    • Full state module template with flow diagram
    • All __virtual__() patterns (5 variations)
    • Error handling examples
    • Common decorators and utilities
  • testing.md - Comprehensive testing guide

    • Test directory structure
    • Unit test templates (legacy and pytest styles)
    • Mocking patterns with examples
    • Running tests (Nox, venv, container)
    • Container testing for CI reproduction
    • Linting and formatting
  • git-and-ci.md - Git workflow and CI

    • Commit guidelines (NO AI attribution!)
    • PR workflow with gh CLI commands
    • Branch strategy
    • CI failure reproduction workflow
    • Container setup and debugging
  • package-building.md - Package Building Guide

    • Building RPMs locally using CI containers
    • Building DEBs locally
    • Creating source tarballs and onedir artifacts
  • troubleshooting.md - Common issues and solutions

    • Import order issues
    • Module discovery problems
    • ZeroMQ issues
    • Python 3.11+ compatibility gotchas
    • Container filesystem behavior
    • Lazy loading behavior
    • Common error messages and fixes

How to Use

Recommended approach: Create a symlink from the root directory to the agent file you want to use.

Creating a symlink keeps your local setup in sync with updates to the canonical instructions:

bash
# From the root of the Salt repository
ln -s agents/CLAUDE.md CLAUDE.md
# or
ln -s agents/CURSOR.md .cursorrules
# or
ln -s agents/GEMINI.md GEMINI.md
# or
ln -s agents/COPILOT.md COPILOT.md

Why symlink?

  • Automatically receives updates when canonical files are updated
  • Links to agents/docs/ work correctly
  • No maintenance required

Alternative: IDE-Specific Configuration

Some tools may allow you to specify a custom path to instruction files in their settings. Consult your tool's documentation.

Note: If you need to customize the instructions, it's better to propose changes to the canonical files in agents/ so everyone benefits, rather than maintaining a personal copy.

MCP Servers

This directory also contains Model Context Protocol (MCP) servers that expose Salt development tools to AI agents:

  • mcp/salt_test/ - Testing tools server
    • Direct pytest execution (quick local testing)
    • CI failure discovery (analyze PR failures)
    • Container testing (reproduce CI failures)

See mcp/README.md for setup and usage instructions.

Quick Setup

  1. Install MCP SDK: pip install mcp
  2. Configure in ~/.config/claude-code/mcp_config.json (see mcp/mcp-config.json for template)
  3. Set GitHub token for CI features: export GITHUB_TOKEN="your_token"

With MCP configured, you can ask Claude:

  • "What tests are failing in PR #68562?"
  • "Run the loader tests locally"
  • "Reproduce the failure from PR #68562 on debian-11"

.gitignore

The root-level instruction files (CLAUDE.md, GEMINI.md, etc.) are intentionally ignored by git to prevent personal configurations from being committed. Only the canonical versions in this directory are tracked.

Contributing

If you discover better patterns, common issues, or ways to improve these instructions:

  1. Edit the appropriate file in this agents/ directory
  2. Submit a pull request with your improvements
  3. Include a brief explanation of what the change helps agents understand better

File Naming Conventions

  • CLAUDE.md - For Claude-based tools
  • GEMINI.md - For Gemini-based tools
  • CURSOR.md - For Cursor IDE (may also be named .cursorrules)
  • COPILOT.md - For GitHub Copilot (may also be named .github/copilot-instructions.md)

Note: Some tools may use different filenames. Check your tool's documentation for the correct filename and location.


Overview (`rfcs/README.md`)

Salt RFCs

This document is in a DRAFT status

Many changes, including bug fixes and documentation improvements can be implemented and reviewed via the normal GitHub pull request workflow.

Some changes though are "substantial", and we ask that these be put through a bit of a design process and produce a consensus among the Salt core team.

The "RFC" (request for comments) process is intended to provide a consistent and controlled path for new features to enter the project.

This process is being actively developed, and it will still change as more features are implemented and the community settles on specific approaches to feature development.

When to follow this process

You should consider using this process if you intend to make "substantial" changes to Salt or its documentation. Some examples that would benefit from an RFC are:

  • A new feature that creates new API surface area
  • The removal of features that already shipped
  • The introduction of new idiomatic usage or conventions

The RFC process is a great opportunity to get more eyeballs on your proposal before it becomes a part of a released version of Salt. Quite often, even proposals that seem "obvious" can be significantly improved once a wider group of interested people have a chance to weigh in.

The RFC process can also be helpful to encourage discussions about a proposed feature as it is being designed, and incorporate important constraints into the design while it's easier to change, before the design has been fully implemented.

Changes that do NOT require an RFC:

  • Rephrasing, reorganizing or refactoring
  • Bug fixes
  • Addition or removal of warnings
  • Additions only likely to be noticed by other implementors-of-Salt, invisible to users-of-Salt.

What the process is

In short, to get a major feature added to Salt, one usually first gets the RFC merged into the repo as a markdown file. At that point the RFC is 'active' and may be implemented with the goal of eventual inclusion into Salt.

The RFC life-cycle

  • Once an RFC becomes active, the feature may be implemented and submitted as a pull request to the Salt repository.
  • This still does not mean the feature will be merged, only that the core team has agreed to it in principle.
  • The fact that a given RFC has been accepted implies nothing about its implementation priority.
  • Modifications to active RFC's can be done in follow-up pull requests.
  • We should strive to write each RFC in a way that it will reflect the final design of the feature; However, if during implementation things change, the RFC document should be updated accordingly.

Implementing an RFC

The author of an RFC is not obligated to implement it. Of course, the RFC author (like any other developer) is welcome to post an implementation for review after the RFC has been accepted.

If you are interested in working on the implementation for an 'active' RFC, but cannot determine if someone else is already working on it, feel free to ask (e.g. by leaving a comment on the associated issue).

Reviewing RFCs

Each week the team will attempt to review some set of open RFC pull requests.

Every accepted feature should have a core team champion, who will represent the feature and its progress.

This RFC process owes its inspiration to the React RFC process, Yarn RFC process, Rust RFC process, and Ember RFC process


Overview (`agents/mcp/README.md`)

Salt AI Agent MCP Servers

This directory contains Model Context Protocol (MCP) servers that expose Salt development tools to AI agents.

What is MCP?

Model Context Protocol (MCP) is a standard for connecting AI assistants to external tools and data sources. MCP servers expose functionality that AI agents can discover and use.

Available Servers

salt-test

Testing tools for Salt development:

  • Direct pytest execution (quick local testing)
  • CI failure discovery (analyze PR failures)
  • Container testing (reproduce CI failures exactly)

See salt_test/README.md for details.

Setup

1. Set Up Virtual Environments

REQUIRED: The Salt repository needs two virtual environments:

  • venv310: For running tests on 3006.x/3007.x branches
  • venv314: For running tests on master branch AND pre-commit hooks
bash
cd /path/to/salt/repo

# Setup venv310
python3.10 -m venv venv310
source venv310/bin/activate
pip install --upgrade pip setuptools wheel
pip install -r requirements/static/pkg/py3.10/linux.lock  # or darwin.lock / windows.lock
pip install -r requirements/pytest.txt
pip install -r requirements/static/ci/py3.10/tools.lock
pip install pre-commit python-tools-scripts
pip install -e .
deactivate

# Setup venv314 (for master branch testing + pre-commit)
python3.14 -m venv venv314
source venv314/bin/activate
pip install --upgrade pip setuptools wheel
pip install -r requirements/static/pkg/py3.14/linux.lock  # or darwin.lock / windows.lock
pip install -r requirements/pytest.txt
pip install -r requirements/static/ci/py3.14/tools.lock
pip install pre-commit python-tools-scripts
pip install -e .
pre-commit install
deactivate

# Verify
./venv310/bin/python -m tools --help

See salt_test/README.md for detailed setup instructions.

2. Install MCP SDK

bash
pip install mcp

3. Configure Claude Code

Add the servers to your Claude Code MCP configuration. The location depends on your setup:

For this repository (relative paths):
Create or edit ~/.config/claude-code/mcp_config.json:

json
{
  "mcpServers": {
    "salt-test": {
      "command": "python3",
      "args": ["-m", "agents.mcp.salt_test.server"],
      "cwd": "/absolute/path/to/salt/repo",
      "env": {
        "PYTHONPATH": "/absolute/path/to/salt/repo"
      }
    }
  }
}

Alternative (using absolute path to server):

json
{
  "mcpServers": {
    "salt-test": {
      "command": "python3",
      "args": ["/absolute/path/to/salt/repo/agents/mcp/salt_test/server.py"],
      "cwd": "/absolute/path/to/salt/repo",
      "env": {}
    }
  }
}

4. Set GitHub Token (for CI failure discovery)

For accessing GitHub API to discover CI failures:

bash
# Option 1: Set environment variable
export GITHUB_TOKEN="your_github_token"

# Option 2: Configure gh CLI
gh auth login

5. Restart Claude Code

After configuration, restart Claude Code to load the MCP servers.

Verifying Setup

Once configured, you can verify the servers are loaded by asking Claude:

text
"What MCP tools are available?"

You should see the salt-test tools listed.

Usage Examples

Quick Local Testing

text
"Run tests/pytests/unit/test_loader.py with verbose output"

Claude will use pytest_run to execute the test locally.

Discover PR Failures

text
"What tests are failing in PR #68562?"

Claude will use ci_pr_failures to analyze the PR's CI runs.

Reproduce CI Failure

text
"Reproduce the test_version.py failure from PR #68562 on debian-11"

Claude will:

  1. Discover the failing test
  2. Guide you through downloading artifacts
  3. Setup the container
  4. Run the test

Development

Adding New Tools

  1. Add functionality to tools/testsuite/ (following existing patterns)
  2. Register the module in tools/__init__.py
  3. Add corresponding MCP tool to salt_test/server.py:
    • Add tool definition in list_tools()
    • Add command mapping in call_tool()
  4. Document in salt_test/README.md

Testing MCP Servers Locally

bash
# Test the server directly
cd /path/to/salt/repo
python3 -m agents.mcp.salt_test.server

# Test with MCP inspector (if available)
mcp-inspector agents.mcp.salt_test.server

Troubleshooting

Server Not Loading

  1. Check Python path is correct in configuration
  2. Verify mcp package is installed: pip install mcp
  3. Check Claude Code logs for errors

Tools Not Working

  1. Verify you're in the Salt repository directory
  2. Check that tools/ infrastructure is working: python3 -m tools --help
  3. For container tools, verify Docker is running: docker info
  4. For CI failure tools, verify GitHub token: echo $GITHUB_TOKEN

Container Issues

  1. Ensure Docker is installed and running
  2. Check container exists: docker ps -a | grep salt-test
  3. Verify artifacts downloaded: ls artifacts/

Architecture

text
agents/mcp/
├── salt_test/
│   ├── server.py          # MCP server implementation
│   ├── README.md          # Tool documentation
│   └── __init__.py
└── README.md              # This file

tools/testsuite/           # Underlying CLI tools
├── pytest.py              # Direct pytest execution
├── ci_failure.py          # CI failure discovery
└── container_test.py      # Container testing

The MCP servers are thin wrappers around the existing tools/ CLI infrastructure, ensuring consistency between CLI and AI agent usage.

Contributing

When adding new testing capabilities:

  1. Implement in tools/testsuite/ first (can be used standalone)
  2. Expose via MCP for AI agent access
  3. Document both CLI and MCP usage
  4. Update agent instruction files (CLAUDE.md, etc.) if needed

Resources


Overview (`pkg/macos/README.md`)

Building Native Packages on macOS

Salt runs well on the macOS, but does have some limitations.

In this directory you will find scripts and collateral to build a macOS
.pkg-style package that uses a custom-built Python. This process has been
tested on macOS Catalina (10.15) and later.

This approach enables Salt users to potentially add items to their Salt install
via 'pip install' without interfering with the rest of their system's Python
packages.

In addition, because of changes in launchd from version to version of the OS, a
simpler approach is taken for the launchd plist files.

To build a native package you will need the following installed:

  • Xcode, or the Xcode Command Line Tools
  • git

The native package will install program files into /opt/salt. Configuration
files will be installed to etc/salt, but will have '.dist' appended to
them.

Launchd plists will be placed in /Library/LaunchDaemons. By default, salt-minion
will NOT be enabled or started.

The process has been automated via the build.sh script in the directory with
this README file. Checkout the Salt repo from GitHub, chdir into the base repo
directory, and run the following:

text
./build.sh

References:

http://crushbeercrushcode.org/2014/01/using-pkgbuild-and-productbuild-on-os-x-10-7/
http://stackoverflow.com/questions/11487596/making-os-x-installer-packages-like-a-pro-xcode-developer-id-ready-pkg


Overview (`pkg/old/README.md`)

The things found in this directory have been deprecated and will be removed in
the 3008.0 release of salt. The Salt maintainers are not aware of anyone
relying on these files. Please file a bug report if you are relying any files
that have been moved to this 'old' directory.


Overview (`pkg/windows/readme.md`)

Packaged Plugin Licenses

The following dependencies are packaged with
salt for Windows with their corresponding licenses:

Module License
backports.ssl-match-hostname PSF
certifi ISC
cffi MIT
CherryPy BSD
cryptography BSD
gitdb BSD
GitPython BSD
idna BSD-like
ioloop MIT
ipaddress PSF
Jinja2 BSD
libnacl Apache
lxml BSD
Mako MIT
MarkupSafe BSD
msgpack Apache 2.0
pip MIT
psutil BSD
pyasn1 BSD
pycparser BSD
pycurl LGPL + MIT
PyMySQL MIT
PyOpenSSL Apache 2.0
python-certifi-win32 BSD
python-dateutil Simplified BSD
python-gnupg BSD
pywin32 PSF
PyYAML MIT
pyzmq LGPL + BSD
requests Apache 2.0
setuptools MIT
singledispatch MIT
smmap BSD
timelib ZLIB/PHP
tornado Apache 2.0
wheel MIT
WMI MIT

Overview (`tests/monitoring/README.md`)

Salt Monitoring Environment

This environment sets up a Salt Master, two Minions, Prometheus, and cAdvisor for monitoring.

Prerequisite

  • Docker and Docker Compose (or Podman and podman-compose)

Note for Podman users: If running in rootless mode, cAdvisor might require additional configuration to access host metrics. You may need to run Podman as root for full cAdvisor functionality, or use podman stats as an alternative.

Usage

  1. Start the environment:

    bash
    docker-compose up -d
  2. Access the Salt Master:

    bash
    docker exec -it salt-master bash
  3. Run a test command:

    bash
    salt '*' test.ping
  4. Access Prometheus:
    Go to http://localhost:9090

  5. Access cAdvisor:
    Go to http://localhost:18081

  6. Access Grafana:
    Go to http://localhost:13000
    The "Salt Monitoring" dashboard is pre-provisioned.

Monitoring for Memory Leaks

In Prometheus, you can use the following query to monitor memory usage of the salt-master container:

promql
container_memory_usage_bytes{container_label_com_docker_compose_service="salt-master"}

Or more specifically for RSS:

promql
container_memory_rss{container_label_com_docker_compose_service="salt-master"}

Configuration

  • master.conf: Salt Master configuration
  • minion.conf: Salt Minion configuration (shared by both minions)
  • prometheus.yml: Prometheus configuration
  • Dockerfile.salt: Dockerfile for Salt components

Overview (`tests/pytests/README.md`)

New Test Suite

Welcome to the new test suite for Salt!

Any test under this directory shall be written exploring the full capabilities of PyTest.
That means, no occurrences of the TestCase class
shall be used, neither our customizations to it.

Purpose

While PyTest can happily run unittest tests(withough taking advantage of most of PyTest's strengths),
this new path in the tests directory was created to provide a clear separation between the two approaches to writing tests.
Some(hopefully all) of the existing unittest tests might get ported to PyTest's style of writing tests, new tests should be added under
this directory tree, and, in the long run, this directory shall become the top level tests directory.


Overview (`.github/actions/ssh-tunnel/README.md`)

SSH Tunnel

The ssh-tunnel action will create a reverse tunnel over webrtc to port 22 on the runner.

Usage

In order to use this action you must have a sdp offer from your local host and a ssh key pair.
Start with creating an sdp offer on your local machine. Provide these values to the ssh-tunnel
action and wait for output from the action with the sdp reply. Provide the reply to the local
rtcforward.py process by pasting it to stdin. If all goes well the local port on your maching
will be forwarded to the ssh port on the runner.

Getting an sdp offer

To get an sdp offer start rtcforward.py on you local machine with the offer command.
You can also specify which port on the local machine will be used for the tunnel.

bash
$ python3 .github/actions/ssh-tunnel/rtcforward.py offer --port 5222

rtcforward.py will create an offer an display it to your terminal. (This example offer has been truncated)
After showing the offer the rtcforward.py process will wait for a reply.

text
-- offer --
eyJzZHAiOiAidj0wXHJcbm89LSAzOTQ3Mzg4NjUzIDM5NDczODg2NTMgSU4gSVA0IDAuMC4wLjBcclxu
cz0tXHJcbnQ9MCAwXHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOldNUyAqXHJc
bm09YXBwbGljYXRpb24gMzUyNjkgRFRMUy9TQ1RQIDUwMDBcclxuYz1JTiBJUDQgMTkyLjE2OC4wLjIw
IHVkcCAxNjk0NDk4ODE1IDE4NC4xNzkuMjEwLjE1MiAzNTI2OSB0eXAgc3JmbHggcmFkZHIgMTkyLjE2
OC4wLjIwMSBycG9ydCAzNTI2OVxyXG5hPWNhbmRpZGF0ZTozZWFjMzJiZTZkY2RkMTAwZDcwMTFiNWY0
NTo4Qzo2MDoxMTpFQTo3NzpDMTo5RTo1QTo3QzpDQzowRDowODpFQzo2NDowQToxM1xyXG5hPWZpbmdl
cnByaW50OnNoYS01MTIgNjY6MzI6RUQ6MDA6N0I6QjY6NTQ6NzA6MzE6OTA6M0I6Mjg6Q0I6QTk6REU6
MzQ6QjI6NDY6NzE6NUI6MjM6ODA6Nzg6Njg6RDA6QTA6QTg6MjU6QkY6MDQ6ODY6NUY6OTA6QUY6MUQ6
QjA6QzY6ODA6QUY6OTc6QTI6MkM6NDI6QUU6MkI6Q0Q6Mjk6RUQ6MkI6ODc6NTU6ODg6NDY6QTM6ODk6
OEY6ODk6OTE6QTE6QTI6NDM6NTc6M0E6MjZcclxuYT1zZXR1cDphY3RwYXNzXHJcbiIsICJ0eXBlIjog
Im9mZmVyIn0=
-- end offer --
-- Please enter a message from remote party --

Getting an sdp answer

Provide the offer to the ssh-tunnel action. When the action runs, an answer to the offer will be generated.
In the action output you will see that the offer was recieved and the reply in the output.

text
-- Please enter a message from remote party --
-- Message received --
-- reply --
eyJzZHAiOiAidj0wXHJcbm89LSAzOTQ3Mzg3NDcxIDM5NDczODc0NzEgSU4gSVA0IDAuMC4wLjBcclxu
cz0tXHJcbnQ9MCAwXHJcbmE9Z3JvdXA6QlVORExFIDBcclxuYT1tc2lkLXNlbWFudGljOldNUyAqXHJc
bm09YXBwbGljYXRpb24gNTcwMzkgRFRMUy9TQ1RQIDUwMDBcclxuYz1JTiBJUDQgMTkyLjE2OC42NC4x
MFxyXG5hPW1pZDowXHJcbmE9c2N0cG1hcDo1MDAwIHdlYnJ0Yy1kYXRhY2hhbm5lbCA2NTUzNVxyXG5h
MTc6MEI6RTA6OTA6QUM6RjU6RTk6RUI6Q0E6RUE6NTY6REI6NTA6QTk6REY6NTU6MzY6MkM6REI6OUE6
MDc6Mzc6QTM6NDc6NjlcclxuYT1maW5nZXJwcmludDpzaGEtNTEyIDMyOjRDOjk0OkRDOjNFOkU5OkU3
OjNCOjc5OjI4OjZDOjc5OkFEOkVDOjIzOkJDOjRBOjRBOjE5OjlCOjg5OkE3OkE2OjZBOjAwOjJFOkM5
OkE0OjlEOjAwOjM0OjFFOjRDOkVGOjcwOkY5OkNBOjg0OjlEOjcxOjI5OkVCOkIxOkREOkFEOjg5OjUx
OkZFOjhCOjI3OjFDOjFBOkJEOjUxOjQ2OjE4OjBBOjhFOjVBOjI1OjQzOjQzOjZGOkRBXHJcbmE9c2V0
dXA6YWN0aXZlXHJcbiIsICJ0eXBlIjogImFuc3dlciJ9
-- end reply --

Finalizing the tunnel

Paste the sdp reply from the running action into the running rtcforward.py process that created the offer.
After receiveing the offer you will see -- Message received -- and tunnel will be created.

text
/* Detailed source-code truncated for AI context efficiency. */

SSH to your local port.

text
ssh -o StrictHostKeychecking=no -o TCPKeepAlive=no -o StrictHostKeyChecking=no -vv -p 5222 runner@localhost

Overview (`.github/workflows/templates/README.md`)

Workflow Templates

The templates are used to generate the actual workflows that run on GitHub Actions.
They use Jinja2 as the template engine.

To Note

Let's try to keep the Jinja usage to the bare minimum because, as time passes,
the complexity just piles up making it harder to read and interpret the templates.

Changes To Default Jinja Syntax

By default Jinja uses {% ... %}, {{ ... }}, {# ... #}, etc to do it's magic.
In order not to clash with the GitHub Actions syntax, and to also avoid having to
add bunch of {% raw %} ... {% endraw %} blocks, we changed some things:

  • Instead of {% and %} use <% and %>
  • Instead of {{ and }} use <{ and }>

The rest of Jinja2 defaults apply.


Overview (`agents/mcp/salt_test/README.md`)

Salt Test MCP Server

Model Context Protocol (MCP) server for Salt testing tools.

Overview

This MCP server exposes Salt testing capabilities to AI agents, enabling:

  1. Quick Local Testing - Run pytest directly for fast iteration
  2. CI Failure Discovery - Analyze failing tests from PRs and CI runs
  3. CI Reproduction - Reproduce failures in CI containers exactly as they occur in GitHub Actions

Available Tools

Local Testing (Quick & Dirty)

`pytest_run`

Run pytest directly with a test path.

Parameters:

  • test_path (required): Test file, directory, or specific test
  • venv_path (optional): Path to virtual environment (defaults to ./venv310)
  • extra_args (optional): Additional pytest arguments

Example:

json
{
  "test_path": "tests/pytests/unit/test_loader.py::test_load_modules",
  "extra_args": ["-v", "-x"]
}

`pytest_last_failed`

Re-run only tests that failed in the last run.

Parameters:

  • venv_path (optional): Path to virtual environment
  • extra_args (optional): Additional pytest arguments

`pytest_pattern`

Run tests matching a pattern (uses pytest -k).

Parameters:

  • pattern (required): Test name pattern
  • test_path (optional): Path to search within
  • venv_path (optional): Virtual environment path
  • extra_args (optional): Additional arguments

Example:

json
{
  "pattern": "auth",
  "extra_args": ["-v"]
}

`pytest_list`

List test files matching a glob pattern.

Parameters:

  • pattern (optional): Glob pattern (defaults to "test_*.py")
  • path (optional): Base path to search

CI Failure Discovery

`ci_pr_failures`

Get all failing tests from a PR's CI runs.

Parameters:

  • pr_number (required): Pull request number
  • repository (optional): Repository (defaults to "saltstack/salt")
  • json_output (optional): Return as JSON

Example:

json
{
  "pr_number": 68562
}

`ci_run_failures`

Get failing tests from a specific CI run.

Parameters:

  • run_id (required): Workflow run ID
  • repository (optional): Repository
  • json_output (optional): Return as JSON

`ci_failure_summary`

Get a human-readable summary of PR failures.

Parameters:

  • pr_number (required): Pull request number
  • repository (optional): Repository

Container Testing (CI Reproduction)

`ci_setup_container`

Setup a container for testing (decompress dependencies, create relenv symlink).

Parameters:

  • container_name (required): Name of container to setup
  • arch (optional): Architecture (x86_64 or arm64, defaults to x86_64)
  • python_version (optional): Python version (e.g., "3.14") - determines if relenv symlink is needed

Example:

json
{
  "container_name": "salt-test-debian-11",
  "arch": "x86_64",
  "python_version": "3.14"
}

`ci_run_test`

Run a test in a CI container.

Parameters:

  • container_name (required): Container name
  • test_path (required): Test path to run
  • extra_args (optional): Additional arguments (e.g., ["--run-slow", "-x", "-v"])

Example:

json
{
  "container_name": "salt-test-debian-11",
  "test_path": "tests/pytests/functional/test_version.py::test_salt_extensions_in_versions_report",
  "extra_args": ["--run-slow", "-x", "-v"]
}

`ci_cleanup`

Clean up artifacts and/or containers.

Parameters:

  • artifacts (optional): Clean up downloaded artifacts
  • containers (optional): Pattern to match container names (e.g., "salt-test-*")

Example:

json
{
  "artifacts": true,
  "containers": "salt-test-*"
}

`ci_list_platforms`

List available CI container platforms.

Parameters: None

Workflows

Workflow 1: Discover PR Failures

text
1. ci_pr_failures(pr_number=68562)
   → Returns list of failing tests by platform

2. Analyze results to identify common failures

Workflow 2: Reproduce Specific Failure

text
1. ci_pr_failures(pr_number=68562)
   → Get run_id and failing test

2. Download artifacts (use existing tools container create/ts setup)

3. ci_setup_container(container_name="salt-test-debian-11", python_version="3.14")

4. ci_run_test(
     container_name="salt-test-debian-11",
     test_path="tests/pytests/functional/test_version.py::test_failure",
     extra_args=["--run-slow", "-x", "-v"]
   )

Workflow 3: Quick Local Test

text
1. pytest_run(
     test_path="tests/pytests/unit/test_loader.py",
     extra_args=["-v", "-x"]
   )

2. If failures, analyze and fix

3. pytest_last_failed()
   → Re-run only failed tests

Installation

  1. Install MCP Python SDK:

    bash
    pip install mcp
  2. Configure Claude Code to use this server (see ../mcp-config.json)

  3. The server will automatically use the Salt repository's tools infrastructure

Usage with Claude Code

Once configured, you can ask Claude:

  • "What tests are failing in PR #68562?"
  • "Run the loader tests locally"
  • "Reproduce the test_version failure from PR #68562 on debian-11"
  • "Re-run the last failed tests"

Requirements

  • Python 3.10 and 3.14 installed
  • MCP Python SDK (pip install mcp)
  • Salt repository with tools/ infrastructure
  • Virtual environments setup (see below)
  • Docker (for container-based testing)
  • GitHub token for CI failure discovery (set GITHUB_TOKEN or configure gh CLI)

Setting Up Virtual Environments

The Salt repository requires two virtual environments:

  • venv310 (Python 3.10): For running tests on 3006.x and 3007.x branches
  • venv314 (Python 3.14): For running tests on master branch AND pre-commit hooks

Setup venv310 (Python 3.10) - For Testing:

bash
cd /path/to/salt/repo
python3.10 -m venv venv310
source venv310/bin/activate
pip install --upgrade pip setuptools wheel

# Install platform-specific dependencies (choose your OS):
pip install -r requirements/static/pkg/py3.10/linux.lock      # Linux
pip install -r requirements/static/pkg/py3.10/darwin.lock     # macOS
pip install -r requirements/static/pkg/py3.10/windows.lock    # Windows

# Install pytest and tools requirements:
pip install -r requirements/pytest.txt
pip install -r requirements/static/ci/py3.10/tools.lock

# Install pre-commit and python-tools-scripts:
pip install pre-commit python-tools-scripts

# Install Salt in editable mode:
pip install -e .

deactivate

Setup venv314 (Python 3.14) - For Master Branch Testing & Pre-commit:

bash
python3.14 -m venv venv314
source venv314/bin/activate
pip install --upgrade pip setuptools wheel

# Install platform-specific dependencies (choose your OS):
pip install -r requirements/static/pkg/py3.14/linux.lock      # Linux
pip install -r requirements/static/pkg/py3.14/darwin.lock     # macOS
pip install -r requirements/static/pkg/py3.14/windows.lock    # Windows

# Install pytest and tools requirements:
pip install -r requirements/pytest.txt
pip install -r requirements/static/ci/py3.14/tools.lock

# Install pre-commit and python-tools-scripts:
pip install pre-commit python-tools-scripts

# Install Salt in editable mode:
pip install -e .

# Install pre-commit hooks:
pre-commit install

deactivate

Environment Usage:

  • venv310: For running tests on 3006.x/3007.x branches, pytest, tools commands
  • venv314: For running tests on master branch, pre-commit hooks, code formatting, linting

Verify setup:

bash
./venv314/bin/python -c "import salt.version; print(salt.version.__version__)"
./venv314/bin/pytest tests/pytests/unit/test_loader.py -v
./venv310/bin/python -m tools --help

CRITICAL: The MCP server uses the tools/ infrastructure which requires these virtual environments to be set up. Without them, the pytest and tools commands will fail.

Development

The MCP server is a thin wrapper around the existing tools/ CLI infrastructure:

  • tools/testsuite/pytest.py - Direct pytest execution
  • tools/testsuite/ci_failure.py - CI failure discovery
  • tools/testsuite/container_test.py - Container testing

This ensures consistency between CLI and MCP usage.


Overview (`pkg/windows/msi/Product-README.md`)

Salt Minion MSI — maintainer notes

Line length: Body text is wrapped to 80 columns. URL-only lines in
Link reference definitions may run longer
because Markdown does not allow splitting long URLs across lines.

Purpose and audience

This file is for people changing the WiX package
(Product.wxs) and C# custom actions
(CustomAction01). It explains MSI concepts as used here,
directory layout (onedir / relenv), and the order of custom actions.

Operators (silent install, properties, msiexec examples) should use
README.md as the primary reference. Link from there to this file
only when editing the installer itself.

Onedir layout (what `[INSTALLDIR]` and `[ROOTDIR]` mean)

  • [INSTALLDIR] — Onedir / relenv binary root (under Program Files by
    default): salt-minion.exe, embedded Python (Lib\, Scripts\, etc.),
    ssm.exe, and PATH entry. Declared in Product.wxs as directory
    INSTALLDIR; written to registry as install_dir.
  • [ROOTDIR] — Minion root_dir (default under ProgramData): conf\,
    var\, logs, caches, user-dropped modules. Directory ROOTDIR (and
    VARDIR under it); registry root_dir.

WiX Util extension is used for util:ServiceConfig and
util:EventSource only — not util:RemoveFolderEx. Folder / bytecode
hygiene is implemented in custom actions (see below), not RemoveFolderEx.

Custom actions in `InstallExecuteSequence`

Order and conditions follow Product.wxs InstallExecuteSequence
(execute phase). Deferred actions use CADH rows (*_CADH) to pass
CustomActionData into *_DECAC.

  1. stopSalt — condition 1 (always); before kill_python_exe. Stops the
    salt-minion service so log files are not locked during validation.
  2. kill_python_exe — (REMOVE ~= "ALL") or WIX_UPGRADE_DETECTED; before
    InstallValidate. Ends Python processes that would hold DLLs open.
  3. clear_python_caches_IMCAC — NOT (REMOVE = "ALL"); after
    kill_python_exe. Clears __pycache__, stray *.pyc, and empty
    dirs under [INSTALLDIR] (see
    CustomAction01Util.clear_python_bytecode_caches_under_dir).
  4. ReadConfig_IMCAC — NOT Installed; before CostInitialize. Reads
    existing minion config; must run before cost / INSTALLDIR is finalized for
    new installs (see notes at end of Standard action sequence).
  5. remove_NSIS_IMCAC — nsis_install_found; before InstallValidate.
    Removes a prior NSIS minion when ARP reports UninstallString (see
    Standard action sequence).
  6. DeleteConfig2_* — CLEAN_INSTALL and ((NOT Installed) or WIX_UPGRADE_DETECTED): CADH before deferred DeleteConfig2_DECAC; deferred
    after InstallInitialize. Clears config/cache before laydown when user
    requests clean install / upgrade clean. Uses the same C# DeleteConfig_DECAC
    entry as item 10 (shared DllEntry in Product.wxs).
  7. MoveInsecureConfig_*, BackupConfig_DECAC, MoveConfig_DECAC
    — various NOT Installed paths before CreateFolders as in Product.wxs.
  8. WriteConfig_* — NOT Installed; CADH before WriteConfig_DECAC;
    deferred after WriteIniValues.
  9. StartServices — START_MINION; sequence 5900.
  10. DeleteConfig_* — REMOVE ~= "ALL": CADH before DeleteConfig_DECAC;
    deferred after RemoveFolders. Full uninstall cleanup. C# DeleteConfig_DECAC
    (also used by DeleteConfig2_DECAC, item 6) calls clear_python_bytecode_caches_under_dir
    on [INSTALLDIR] first, then removes Scripts / bin and config
    trees per CLEAN_INSTALL / REMOVE_CONFIG.

VC143 feature — Hidden merge of Microsoft VC++ 2022 CRT
(MSM_VC143_CRT .msm); skipped when VCREDIST_INSTALLED registry probe says
already present. See VC++ runtime below.

Product attributes

UpgradeCode

GUID defining the product across versions. E.g. a previous version is
uninstalled during upgrade.
In other words: for update (or upgrade), Windows Installer relies on the
UpgradeCode attribute of the Product tag.
Keep the same UpgradeCode GUID as long as you want the products to be upgraded
by the installer.

Id

WiX

The product code GUID for the product. Type: AutogenGuid

MS:
The product code is a GUID that is the principal identification of an
application or product.

MS:
This ID must vary for different versions and languages.

MS

The product code must be changed if any of the following are true for the
update:

  • The name of the .msi file has been changed.

MS:
A major upgrade is a comprehensive update of a product that needs a change of
the ProductCode Property.
A typical major upgrade removes a previous version of an application and
installs a new version.

A constant Product code GUID is (only) useful for a subsequent mst (transform).
To be safe for a major upgrade, the Id (product code GUI) is
dynamic/autogenerated: * (star)

Therefore: we use dynamic/autogenerated: * (star)

Conditions (for install)

doc

expression-syntax

The XML CDATA Section is safer.

Properties

Most important documentation:
Naming conventions

  • Public properties may be changed by the user and must be upper-case.

Logic value and checkboxes:

  • A msi property is false if and only if it is unset, undefined, missing, the
    empty string (msi properties are strings).
  • A checkbox is empty if and only if the relevant msi property is false.

OS Properties

  • MsiNTProductType: 1=Workstation 2=Domain controller 3=Server
  • VersionNT:
    • Windows 7=601 msdn
    • Windows 10=603 ms
  • PhysicalMemory
    ms

msi properties, use in custom actions:

  • DECAC = "Deferred custom action in C#"
  • IMCAC = "Immediate custom action in C#" — reads MSI properties via
    session["..."] (not CustomActionData). In this project the _DECAC
    suffix is for deferred CAs that use a CADH; immediate DLL exports use
    _IMCAC even when WiX Execute is immediate or firstSequence.
  • CADH = "Custom action data helper"
  • The CADH helper must mention each msi property or the DECAC function will
    crash:
  • A DECAC that tries to use a msi property not listed in its CADH crashes.

Example:

In the CADH:

text
master=[MASTER];minion_id=[MINION_ID]

In the DECAC:

text
session.CustomActionData["master"]      THIS IS OK
session.CustomActionData["mister"]      THIS WILL CRASH

Conditional removal of lifetime data

"Lifetime data" means any change that was not installed by the msi (during the
life time of the application).

When uninstalling an application, an msi only removes exactly the data it
installed, unless explicit actions are taken.

Salt creates life time data which must be removed, some of it during upgrade,
all of it (except configuration) during uninstall.

This package does not use util:RemoveFolderEx for those trees; behavior is
implemented in C# custom actions and WiX sequencing instead:

  • Under [INSTALLDIR] (onedir / relenv root), Python bytecode such as
    __pycache__ trees and stray *.pyc is not fully MSI-owned; clearing
    it on upgrade/repair is appropriate (see clear_python_caches_IMCAC in
    Product.wxs and CustomAction01Util).
  • Under [ROOTDIR] (minion root_dir: logs, var, extmods, custom drops,
    etc.), we restrict deletion to full uninstall only (REMOVE ~= "ALL").

Delete minion_id file

Alternatives

https://wixtoolset.org/documentation/manual/v3/xsd/wix/removefile.html

https://stackoverflow.com/questions/7120238/wix-remove-config-file-on-install

Sequences

An msi is no linear program.
To understand when custom actions will be executed, one must look at the
condition within the tag and Before/After:

On custom action conditions:
Common-MSI-Conditions.pdf
ms

On the upgrade custom action condition:

Property Comment
UPGRADINGPRODUCTCODE does not work
Installed per-machine or per-user install
Not Installed there is no previous version with the same UpgradeCode
REMOVE ~= "ALL" Uninstall

Custom action introduction

Articles

"Installation Phases and In-Script Execution Options for Custom Actions in
Windows Installer"
http://www.installsite.org/pages/en/isnews/200108/

Standard action sequence

Standard actions reference

Standard actions WiX default sequence

coding bee on Standard actions WiX default sequence

You get error LGHT0204 when After or Before are wrong. Example:

text
remove_NSIS_IMCAC is an immediate C# in-script custom action. In
Product.wxs it is sequenced `Before="InstallValidate"` in
`InstallExecuteSequence` with `Execute="immediate"`.

When an NSIS-based Salt Minion is present, remove_NSIS_IMCAC runs the
installed uninst.exe with /S only (no temp copy; NSIS infers install
dir from the uninstaller path). After the stub exits, it polls until
ssm.exe under that install dir is gone (NSIS removes it; the directory may
remain; up to 600s). WMI reports matching NSIS Un*.exe children for
logging while waiting. NSIS_UNINSTALLSTRING comes from WiX ARP
UninstallString.

clear_python_caches_IMCAC (immediate, sequenced After="kill_python_exe",
not on REMOVE="ALL"): walks [INSTALLDIR] and removes every
__pycache__ directory (deepest-first), then stray *.pyc, then prunes
empty directories (deepest-first), so runtime bytecode not tracked by the MSI
does not survive upgrades. The same clear_python_bytecode_caches_under_dir
logic also runs at the start of deferred DeleteConfig_DECAC (full
uninstall, REMOVE ~= "ALL") and whenever DeleteConfig2_DECAC invokes that
same C# method (CLEAN_INSTALL / upgrade path; see items 6 and 10 above).

Notes on ReadConfig_IMCAC

text
Note 1:
  Problem: INSTALLDIR was not set in ReadConfig_IMCAC
  Solution:
  ReadConfig_IMCAC must not be called BEFORE FindRelatedProducts, but
  BEFORE MigrateFeatureStates because INSTALLDIR in only set in
  CostFinalize, which comes after FindRelatedProducts
  Maybe one could call ReadConfig_IMCAC AFTER FindRelatedProducts
Note 2:
  ReadConfig_IMCAC is in both InstallUISequence and InstallExecuteSequence,
  but because it is declared Execute='firstSequence', it will not be
  repeated in InstallExecuteSequence if it has been called in
  InstallUISequence.

Don't allow downgrade

http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html

VC++ runtime (what this MSI ships)

The minion ships as onedir with an embedded Python and native dependencies.
Product.wxs merges the Microsoft Visual C++ 2022 CRT via
WiX Merge modules:

  • MSM_VC143_CRT — Microsoft_VC143_CRT_x64.msm or _x86.msm from
    $(var.WEBCACHE_DIR) (see build_pkg.ps1 for download URLs
    and SHA-256 checks).
  • Feature VC143 (hidden) references that merge; Condition Level="0"
    skips install when VCREDIST_INSTALLED registry search reports the
    runtime already present (see Product.wxs).

Merge-module packaging follows the WiX
how-to. Developers extending the build with extra
native wheels may still need a full MSVC toolchain on the build machine;
see PythonWiki for background.

Images

Images:

  • Dimensions of images must follow WiX rules
  • WixUIDialogBmp must be transparent

Create Product-imgLeft.png from panel.bmp:

  • Open paint3D:
    • new image, ..., canvas options: Transparent canvas off, Resize image with
      canvas NO, Width 493 Height 312
    • paste panel.bmp, move to the left, save as

Note on Create folder

text
Function `win_verify_env()` in `salt/utils/verify.py` sets permissions
      on each start of the salt-minion service. The installer must create
      **`[ROOTDIR]`** (and related dirs) with the same effective permissions
      so they stay in sync with what the minion enforces at runtime.

      The `Permission` element(s) in Product.wxs replace any present
      permissions, except `NT AUTHORITY\SYSTEM:(OI)(CI)(F)`, which seems to be
      the basis. Therefore, you don't need to specify
      `User="[WIX_ACCOUNT_LOCALSYSTEM]"` `GenericAll="yes"`.

      Use `icacls` to test the result (adjust paths to your `ROOTDIR`, e.g.
      `C:\ProgramData\Salt Project\Salt`):

        C:\>icacls "C:\ProgramData\Salt Project\Salt"
        ... BUILTIN\Administrators:(OI)(CI)(F)
            NT AUTHORITY\SYSTEM:(OI)(CI)(F)
        ~~ read ~~
        (object inherit)(container inherit)(full access)

        C:\>icacls "C:\ProgramData\Salt Project\Salt\conf"
        ... BUILTIN\Administrators:(I)(OI)(CI)(F)
            NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
        ~~ read ~~
        (permission inherited from parent container)(object inherit)
        (container inherit)(full access)

      Maybe even the Administrator group full access is "basis", so there is
      no result of the instruction,
      I leave it for clarity, and potential future use.

Set permissions of the install folder with WixQueryOsWellKnownSID

doc

Markdown link targets (see line-length note at top of this file).


Overview (`pkg/windows/msi/Product-discover-files-README.md`)

2016-11-16 mkr
This regards ISSUE 1
https://github.com/markuskramerIgitt/salt-windows-msi/issues/1
uninstall removes the configuration file

Heat collects files into XML file salt-windows-msi\wix\MinionMSI\dist-amd64.wxs

The entry for conf/minion has a Guid:

text
<Component Id="cmpF3CE08C037F32A1C76DF93B02A6ACB79" Directory="dirA7CC33A34163812EEAF3B20CD074A564" Guid="{357ECA3A-24C0-49C5-9964-6CF9504168C4}">
            <File Id="filF7B75C18646D054B4C42FBFF0826EBA7" KeyPath="yes" Source="$(var.dist)\conf\minion" />
        </Component>

Having a Guid means that Wix treats conf/minion as part of the installation
On uninstall, WiX removed all parts of the installation, so also conf/minion.

This is unwanted behaviour.

Approach 1: FAIL
exclude the component
BuildDistFragment.xsl does that.
It filters out ssm.exe, so ssm.exe is not in salt-windows-msi\wix\MinionMSI\dist-amd64.wxs
ssm.exe is added manually in services.wxs.
FAILURE (I think) because then conf would not be installed.

Approach 2:
Remove the GUID of the component.

http://stackoverflow.com/questions/11848780/use-ends-with-in-xslt-v1-0

set attribute to a value while copying:
http://stackoverflow.com/questions/1137078/xslt-do-not-match-certain-attributes/12919373#12919373


Overview (`pkg/windows/msi/README.md`)

Salt Minion msi installer

The installer offers properties for unattended/silent installations.

Example: install silently, set the master, don't start the service:

In cmd:

msiexec /i *.msi MASTER=salt2 START_MINION=""

In powershell (you have to escape the quotes to disable starting the minion service):

msiexec /i *.msi MASTER=salt2 START_MINION=`"`"

Example: uninstall and remove configuration

MsiExec.exe /X *.msi REMOVE_CONFIG=1

Notes

  • Maintainer notes for Product.wxs and C# custom actions: see
    Product-README.md in this directory.
  • The installer requires a privileged user
  • Properties must be upper case
  • Values of properties are case sensitive
  • Values must be quoted when they contain whitespace, or to unset a property, as in START_MINION=""
  • In powershell, you must escape the quotes with a back tick for an empty string, ie: START_MINION=`"`"
  • /l*v Creates a verbose log file, by default %TEMP%\MSIxxxxx.LOG, where xxxxx is random. The name of the log can be specified with msiexec /l*v example.log
  • /qn or /quiet installs quietly, suppressing all dialog boxes
  • /qb or /passive installs quietly but displays a simple progress bar

Properties

Property Default value Comment
MASTER salt The master (name or IP). Separate multiple masters by comma.
MASTER_KEY The master public key. See below.
MINION_ID Hostname The minion id.
MINION_CONFIG Content to be written to the minion config file. See below.
START_MINION 1 Set to "" to prevent the start of the salt-minion service. In powershell you must excape each quotation mark with a back tick (`"`")
MOVE_CONF Set to 1 to move configuration from C:\salt to %ProgramData%.
REMOVE_CONFIG Set to 1 to remove configuration on uninstall. Implied by MINION_CONFIG.
CLEAN_INSTALL Set to 1 to remove configuration and cache before install or upgrade.
CONFIG_TYPE Existing Set to Custom or Default for scenarios below.
CUSTOM_CONFIG Name of a custom config file in the same path as the installer or full path. Requires CONFIG_TYPE=Custom. ONLY FROM COMMANDLINE
INSTALLDIR Windows default Where to install binaries.
ROOTDIR C:\ProgramData\Salt Project\Salt Where to install configuration.
ARPSYSTEMCOMPONENT Set to 1 to hide "Salt Minion" in "Programs and Features".

Master and id are read from file conf\minion

You can set a master with MASTER.

You can set a master public key with MASTER_KEY, after you converted it into one line like so:

  • Remove the first and the last line (-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----).
  • Remove linebreaks.

Property ``MINION_CONFIG``

If MINION_CONFIG is set:

  • Its content is written to configuration file conf\minion, with ^ replaced by line breaks
  • All prior configuration is deleted:
    • all minion.d\*.conf files
    • the minion_id file
  • Implies REMOVE_CONFIG=1: uninstall will remove all configuration.

Example MINION_CONFIG="master: Anna^id: Bob" results in:

text
master: Anna
id: Bob

Property ``CONFIG_TYPE``

There are 3 scenarios the installer tries to account for:

  1. existing-config
  2. custom-config
  3. default-config

Existing

This setting makes no changes to the existing config and just upgrades/downgrades salt.
Makes for easy upgrades. Just run the installer with a silent option.
If there is no existing config, then the default is used and master and minion id are applied if passed.

Custom

This setting will lay down a custom config passed via the command line.
Since we want to make sure the custom config is applied correctly, we'll need to back up any existing config.

  1. minion config renamed to minion-<timestamp>.bak
  2. minion_id file renamed to minion_id-<timestamp>.bak
  3. minion.d directory renamed to minion.d-<timestamp>.bak
    Then the custom config is laid down by the installer... and master and minion id should be applied to the custom config if passed.

Default

This setting will reset config to be the default config contained in the pkg.
Therefore, all existing config files should be backed up

  1. minion config renamed to minion-<timestamp>.bak
  2. minion_id file renamed to minion_id-<timestamp>.bak
  3. minion.d directory renamed to minion.d-<timestamp>.bak
    Then the default config file is laid down by the installer... settings for master and minion id should be applied to the default config if passed

Previous installation in C:\salt and how to install into C:\salt

A previous installation or configuration in C:\salt causes an upgrade into C:\salt, unless you set MOVE_CONF=1.
Set the two properties INSTALLDIR=c:\salt ROOTDIR=c:\salt to install binaries and configuration into C:\salt.

Client requirements

  • Windows 7 (for workstations), Server 2012 (for domain controllers), or higher.

Overview (`scripts/suse/dpkg/README.md`)

What it is

Debian base package to notify installation of new packages outside the control of salt.

Installation

This script depends on python package, so python3 should be installed on the machine

  • The 99dpkgnotify file must be installed in /etc/apt/apt.conf.d/99dpkgnotify
  • The dpkgnotify file must be installed in /usr/bin/dpkgnotify

Overview (`pkg/windows/msi/tests/README.md`)

Run `../../test-copy_mock_files_to_salt_repo.cmd`

  • Use test configuration

Edit a `*.test` file

  • Contains the msi-properties, of which master and minion_id simulate user input via the GUI
  • May contain the dormant keyword, which means the configuration remains (dormant) after uninstall
  • Without the dormant keyword, no configuration must exist after uninstall

Optionally edit a `*.minion_id` file

  • Contains prior configuration by conf/minion_id file
  • Omit this file if there is no prior conf/minion_id configuration

Optionally edit a `*.input` file

  • Contains prior configuration by conf/minion file
  • Omit this file if there is no prior conf/minion configuration

Edit a `*.expected` file

  • Contains the expected configuration (after install). Any difference will result in failure.
  • If the test fails, the resulting configuration will be stored as *.output

Run `test.cmd`

  • Will generate and run *-install.bat and *-uninstall.bat files for each *.test file

Overview (`scripts/suse/yum/plugins/README.md`)

What it is

Plugin which provides a notification mechanism to Salt, if Yum is
used outside of it.

Installation

Configuration files are going to:

text
`/etc/yum/pluginconf.d/[name].conf`

Plugin itself goes to:

text
`/usr/share/yum-plugins/[name].conf`

Permissions

User: root
Group: root
Mode: 644


Overview (`scripts/suse/zypper/plugins/commit/README.md`)

Zypper plugins

Plugins here are required to interact with SUSE Manager in conjunction of SaltStack and Zypper.


Doc Contents (`doc/contents.rst`)

.. _table-of-contents:

====================== Salt Table of Contents

.. toctree::
:maxdepth: 2

text
topics/about_salt_project
topics/index
topics/salt_system_architecture
topics/contributing-guide
topics/maintenance-policy
topics/installation/index
topics/configuration/index
topics/using_salt
topics/execution/index
topics/states/index
topics/return_codes/index
topics/utils/index
topics/event/index
topics/tracing/index
topics/metrics/index
topics/orchestrate/index
topics/solaris/index
topics/ssh/index
topics/thorium/index
topics/cloud/index
topics/proxyminion/index
topics/resources/index
topics/network_automation/index
topics/virt/index
topics/packaging/index
ref/cli/index
ref/pillar/index
ref/tops/index
ref/index
topics/api
topics/topology/index
topics/cache/index
topics/performance/index
topics/slots/index
topics/windows/index
topics/development/index
topics/releases/index
topics/venafi/index
glossary

Doc Faq (`doc/faq.rst`)

.. _faq:

Frequently Asked Questions

.. contents:: FAQ

Is Salt open-core?

No. Salt is 100% committed to being open-source, including all of our APIs. It
is developed under the Apache 2.0 license_, allowing it to be used in both
open and proprietary projects.

To expand on this a little:

There is much argument over the actual definition of "open core". From our standpoint, Salt is open source because

  1. It is a standalone product that anyone is free to use.
  2. It is developed in the open with contributions accepted from the community for the good of the project.
  3. There are no features of Salt itself that are restricted to separate proprietary products distributed by VMware, Inc.
  4. Because of our Apache 2.0 license, Salt can be used as the foundation for a project or even a proprietary tool.
  5. Our APIs are open and documented (any lack of documentation is an oversight as opposed to an intentional decision by SaltStack the company) and available for use by anyone.

SaltStack the company does make proprietary products which use Salt and its libraries, like company is free to do, but we do so via the APIs, NOT by forking Salt and creating a different, closed-source version of it for paying customers.

.. _Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0.html

I think I found a bug! What should I do?

The salt-users mailing list as well as the Community Discord can both be helpful
resources to confirm if others are seeing the issue and to assist with
immediate debugging.

To report a bug to the Salt project, please follow the instructions in
:ref:reporting a bug <reporting-bugs>.

What ports should I open on my firewall?

Minions need to be able to connect to the Master on TCP ports 4505 and 4506.
Minions do not need any inbound ports open. More detailed information on
firewall settings can be found :ref:here <firewall>.

I'm seeing weird behavior (including but not limited to packages not installing their users properly)

This is often caused by SELinux. Try disabling SELinux or putting it in
permissive mode and see if the weird behavior goes away.

My script runs every time I run a *state.apply*. Why?

You are probably using :mod:cmd.run <salt.states.cmd.run> rather than
:mod:cmd.wait <salt.states.cmd.wait>. A :mod:cmd.wait <salt.states.cmd.wait> state will only run when there has been a change in a
state that it is watching.

A :mod:cmd.run <salt.states.cmd.run> state will run the corresponding command
every time (unless it is prevented from running by the unless or onlyif
arguments).

More details can be found in the documentation for the :mod:cmd <salt.states.cmd> states.

When I run *test.ping*, why don't the Minions that aren't responding return anything? Returning ``False`` would be helpful.

When you run test.ping the Master tells Minions to run commands/functions,
and listens for the return data, printing it to the screen when it is received.
If it doesn't receive anything back, it doesn't have anything to display for
that Minion.

There are a couple options for getting information on Minions that are not
responding. One is to use the verbose (-v) option when you run salt
commands, as it will display "Minion did not return" for any Minions which time
out.

.. code-block:: bash

text
salt -v '*' pkg.install zsh

Another option is to use the :mod:manage.down <salt.runners.manage.down>
runner:

.. code-block:: bash

text
salt-run manage.down

Also, if the Master is under heavy load, it is possible that the CLI will exit
without displaying return data for all targeted Minions. However, this doesn't
mean that the Minions did not return; this only means that the Salt CLI timed
out waiting for a response. Minions will still send their return data back to
the Master once the job completes. If any expected Minions are missing from the
CLI output, the :mod:jobs.list_jobs <salt.runners.jobs.list_jobs> runner can
be used to show the job IDs of the jobs that have been run, and the
:mod:jobs.lookup_jid <salt.runners.jobs.lookup_jid> runner can be used to get
the return data for that job.

.. code-block:: bash

text
salt-run jobs.list_jobs
salt-run jobs.lookup_jid 20130916125524463507

If you find that you are often missing Minion return data on the CLI, only to
find it with the jobs runners, then this may be a sign that the
:conf_master:worker_threads value may need to be increased in the master
config file. Additionally, running your Salt CLI commands with the -t
option will make Salt wait longer for the return data before the CLI command
exits. For instance, the below command will wait up to 60 seconds for the
Minions to return:

.. code-block:: bash

text
salt -t 60 '*' test.ping

How does Salt determine the Minion's id?

If the Minion id is not configured explicitly (using the :conf_minion:id
parameter), Salt will determine the id based on the hostname. Exactly how this
is determined varies a little between operating systems and is described in
detail :ref:here <minion-id-generation>.

I'm trying to manage packages/services but I get an error saying that the state is not available. Why?

Salt detects the Minion's operating system and assigns the correct package or
service management module based on what is detected. However, for certain custom
spins and OS derivatives this detection fails. In cases like this, an issue
should be opened on our tracker_, with the following information:

  1. The output of the following command:

    .. code-block:: bash

    salt grains.items | grep os

  2. The contents of /etc/lsb-release, if present on the Minion.

.. _tracker: https://github.com/saltstack/salt/issues

Why aren't my custom modules/states/etc. available on my Minions?

Custom modules are synced to Minions when
:py:func:saltutil.sync_modules <salt.modules.saltutil.sync_modules>,
or :py:func:saltutil.sync_all <salt.modules.saltutil.sync_all> is run.

Similarly, custom states are synced to Minions when :py:func:saltutil.sync_states <salt.modules.saltutil.sync_states>, or :py:func:saltutil.sync_all <salt.modules.saltutil.sync_all> is run.

They are both also synced when a :ref:highstate <running-highstate> is
triggered.

As of the 2019.2.0 release, as well as 2017.7.7 and 2018.3.2 in their
respective release cycles, the sync argument to :py:func:state.apply <salt.modules.state.apply_>/:py:func:state.sls <salt.modules.state.sls> can
be used to sync custom types when running individual SLS files.

Other custom types (renderers, outputters, etc.) have similar behavior, see the
documentation for the :py:func:saltutil <salt.modules.saltutil> module for more
information.

:ref:This reactor example <minion-start-reactor> can be used to automatically
sync custom types when the minion connects to the master, to help with this
chicken-and-egg issue.

Module ``X`` isn't available, even though the shell command it uses is installed. Why?

This is most likely a PATH issue. Did you custom-compile the software which the
module requires? RHEL/CentOS/etc. in particular override the root user's path
in /etc/init.d/functions, setting it to /sbin:/usr/sbin:/bin:/usr/bin,
making software installed into /usr/local/bin unavailable to Salt when the
Minion is started using the initscript. In version 2014.1.0, Salt will have a
better solution for these sort of PATH-related issues, but recompiling the
software to install it into a location within the PATH should resolve the
issue in the meantime. Alternatively, you can create a symbolic link within the
PATH using a :mod:file.symlink <salt.states.file.symlink> state.

.. code-block:: yaml

text
/usr/bin/foo:
  file.symlink:
    - target: /usr/local/bin/foo

.. _which-version:

Can I run different versions of Salt on my Master and Minion?

This depends on the versions. In general, it is recommended that Master and
Minion versions match.

When upgrading Salt, the master(s) should always be upgraded first. Backwards
compatibility for minions running newer versions of salt than their masters is
not guaranteed.

Whenever possible, backwards compatibility between new masters
and old minions will be preserved. Generally, the only exception to this
policy is in case of a security vulnerability.

Recent examples of backwards compatibility breakage include the 0.17.1 release
(where all backwards compatibility was broken due to a security fix), and the
2014.1.0 release (which retained compatibility between 2014.1.0 masters and
0.17 minions, but broke compatibility for 2014.1.0 minions and older masters).

Does Salt support backing up managed files?

Yes. Salt provides an easy to use addition to your file.managed states that
allow you to back up files via :ref:backup_mode <file-state-backups>,
backup_mode can be configured on a per state basis, or in the minion config
(note that if set in the minion config this would simply be the default
method to use, you still need to specify that the file should be backed up!).

Is it possible to deploy a file to a specific minion, without other minions having access to it?

The Salt fileserver does not yet support access control, but it is still
possible to do this. As of Salt 2015.5.0, the
:mod:file_tree <salt.pillar.file_tree> external pillar is available, and
allows the contents of a file to be loaded as Pillar data. This external pillar
is capable of assigning Pillar values both to individual minions, and to
:ref:nodegroups <targeting-nodegroups>. See the :mod:documentation <salt.pillar.file_tree> for details on how to set this up.

Once the external pillar has been set up, the data can be pushed to a minion
via a :py:func:file.managed <salt.states.file.managed> state, using the
contents_pillar argument:

.. code-block:: yaml

text
/etc/my_super_secret_file:
  file.managed:
    - user: secret
    - group: secret
    - mode: 600
    - contents_pillar: secret_files:my_super_secret_file

In this example, the source file would be located in a directory called
secret_files underneath the file_tree path for the minion. The syntax for
specifying the pillar variable is the same one used for :py:func:pillar.get <salt.modules.pillar.get>, with a colon representing a nested dictionary.

.. warning::
Deploying binary contents using the :py:func:file.managed <salt.states.file.managed> state is only supported in Salt 2015.8.4 and
newer.

.. _faq-restart-salt-minion:

What is the best way to restart a Salt Minion daemon using Salt after upgrade?

Updating the salt-minion package requires a restart of the salt-minion
service. On systemd systems the shipped salt-minion.service unit sets
KillMode=mixed, and the RPM's %pre scriptlet issues a blocking
systemctl stop salt-minion.service so ownership-restoration chown
calls do not race a live minion. On its own that stop would deadlock a
minion-driven upgrade -- the stop waits for every process in the cgroup to
exit, including the salt worker running the state; the worker is blocked in
dnf; dnf is blocked in %pre -- and after TimeoutStopSec
systemd would SIGKILL the whole cgroup, losing the state return
(issue #69656). Starting with 3006.28 the %pre minion scriptlet detects
this "minion is upgrading itself" case (by walking the scriptlet's parent
process chain and looking for salt-minion.service in the cgroup) and
skips the blocking stop; %post and %posttrans then leave the still-
running minion alone. The state run's pkg.installed returns normally,
and the FAQ pattern below performs the actual restart in a detached child
after the state completes.

The remainder of this entry covers the cases that still need explicit
handling:

  • legacy non-systemd init systems on Debian-derived distributions, where
    invoke-rc.d may restart the service immediately after dpkg unpacks
    the new package;
  • Windows, where the installer replaces the binary and re-creates the
    salt-minion service;
  • orchestration that needs to block until the upgraded minion reports back.

Older releases of this FAQ recommended writing a policy-rc.d shim with
file.managed and a prereq requisite. That approach is no longer
recommended: see issue #61078_ for the loader error it triggers on recent
releases. Use the patterns below instead.

.. _issue #61078: https://github.com/saltstack/salt/issues/61078

Restart in the background from a state


The simplest reliable pattern is to use service.restart with bg: True
so the restart runs detached from the state run:

.. code-block:: jinja

text
Upgrade Salt Minion:
  pkg.installed:
    - name: salt-minion

Restart Salt Minion:
  cmd.run:
    - name: 'salt-call --local service.restart salt-minion'
    - bg: True
    - onchanges:
      - pkg: Upgrade Salt Minion

--local keeps the call self-contained so the restart does not depend on a
master round-trip. bg: True forks the salt-call process so it survives
the parent salt-minion service restart; the running state and its return
to the master are not interrupted.

Restart from the master


To restart a fleet of minions from the master without waiting for the
disconnect, use cmd.run_bg:

.. code-block:: bash

text
salt -G 'kernel:Windows'     cmd.run_bg 'salt-call --local service.restart salt-minion'
salt -C 'not G@kernel:Windows' cmd.run_bg 'salt-call --local service.restart salt-minion'

A note on Windows


Restarting the salt-minion service on Windows is not normally required as
part of an upgrade. The installer stops the service, replaces the binaries,
recreates the service, and starts it again. A restart is only needed if the
minion configuration was changed after installation.

Avoiding the post-install restart on non-systemd Debian/Ubuntu


On non-systemd Debian-family systems the salt-minion package's
invoke-rc.d call may restart the service immediately after dpkg unpacks
the new package. Where a policy-rc.d shim is needed, install it directly
with file.managed as a separate state run (orchestrated from the master
ahead of the upgrade run), not via prereq inside the same SLS that runs
pkg.installed. Inlining the policy shim with prereq is the configuration
that triggered the loader error reported in issue #61078.

Waiting for minions to come back online


A common issue in performing automated restarts of a salt minion, for example during
an orchestration run, is that it will break the orchestration since the next statement
is likely to be attempted before the minion is back online. This can be remedied
by inserting a blocking waiting state that only returns when the selected minions
are back up (note: this will only work in orchestration states since manage.up
needs to run on the master):

.. code-block:: jinja

text
Wait for salt minion:
  loop.until_no_eval:
    - name: saltutil.runner
    - expected:
        - my_minion
    - args:
        - manage.up
    - kwargs:
        tgt: my_minion
    - period: 3
    - init_wait: 3

This will, after an initial delay of 3 seconds, execute the manage.up-runner
targeted specifically for my_minion. It will do this every period seconds
until the expected data is returned. The default timeout is 60s but can be configured
as well.

Salting the Salt Master

In order to configure a master server via states, the Salt master can also be
"salted" in order to enforce state on the Salt master as well as the Salt
minions. Salting the Salt master requires a Salt minion to be installed on
the same machine as the Salt master. Once the Salt minion is installed, the
minion configuration file must be pointed to the local Salt master:

.. code-block:: yaml

text
master: 127.0.0.1

Once the Salt master has been "salted" with a Salt minion, it can be targeted
just like any other minion. If the minion on the salted master is running, the
minion can be targeted via any usual salt command. Additionally, the
salt-call command can execute operations to enforce state on the salted
master without requiring the minion to be running.

More information about salting the Salt master can be found in the salt-formula
for salt itself:

https://github.com/saltstack-formulas/salt-formula

Restarting the salt-master service using execution module or application of
state could be done the same way as for the Salt minion described :ref:above <faq-restart-salt-minion>.

.. _faq-grain-security:

Is Targeting using Grain Data Secure?

.. include:: _incl/grains_passwords.rst

Because grains can be set by users that have access to the minion configuration
files on the local system, grains are considered less secure than other
identifiers in Salt. Use caution when targeting sensitive operations or setting
pillar values based on grain data.

The only grain which can be safely used is grains['id'] which contains the Minion ID.

When possible, you should target sensitive operations and data using the Minion
ID. If the Minion ID of a system changes, the Salt Minion's public key must be
re-accepted by an administrator on the Salt Master, making it less vulnerable
to impersonation attacks.

Why Did the Value for a Grain Change on Its Own?

This is usually the result of an upstream change in an OS distribution that
replaces or removes something that Salt was using to detect the grain.
Fortunately, when this occurs, you can use Salt to fix it with a command
similar to the following:

.. code-block:: bash

text
salt -G 'grain:ChangedValue' grains.setvals "{'grain': 'OldValue'}"

(Replacing grain, ChangedValue, and OldValue with
the grain and values that you want to change / set.)

You should also file an issue <https://github.com/saltstack/salt/issues>_
describing the change so it can be fixed in Salt.


Doc Glossary (`doc/glossary.rst`)

.. _glossary:

======== Glossary

.. glossary::

text
Auto-Order
    The evaluation of states in the order that they are defined in a SLS
    file. *See also*: :ref:`ordering <ordering_auto_order>`.

Bootstrap
    A stand-alone Salt project which can download and install a Salt master
    and/or a Salt minion onto a host. *See also*: `salt-bootstrap
    <https://github.com/saltstack/salt-bootstrap>`_.

Compound Matcher
    A combination of many target definitions that can be combined with
    boolean operators. *See also*: :ref:`targeting <targeting-compound>`.

EAuth
    Shorthand for 'external authentication'. A system for calling to a
    system outside of Salt in order to authenticate users and determine if
    they are allowed to issue particular commands to Salt. *See also*:
    :ref:`external auth<acl-eauth>`.

Environment
    A directory tree containing state files which can be applied to
    minions. *See also*: :ref:`top file<states-top-environments>`.

Execution Function
    A Python function inside an Execution Module that may take arguments
    and performs specific system-management tasks. *See also*: :ref:`the
    list of execution modules <all-salt.modules>`.

External Job Cache
    An external data-store that can archive information about jobs that
    have been run. A default returner. *See also*:
    :conf_master:`ext_job_cache`, :ref:`the list of returners
    <all-salt.returners>`.

Execution Module
    A Python module that contains execution functions which directly
    perform various system-management tasks on a server. Salt ships with a
    number of execution modules but users can also write their own
    execution modules to perform specialized tasks. *See also*: :ref:`the
    list of execution modules <all-salt.modules>`.

External Pillar
    A module that accepts arbitrary arguments and returns a dictionary.
    The dictionary is automatically added to a pillar for a minion.

Event
    A notice emitted onto an event bus. Events are often driven by requests
    for actions to occur on a minion or master and the results of those
    actions. *See also*: :ref:`Salt Reactor <reactor>`.

File Server
    A local or remote location for storing both Salt-specific files such as
    top files or SLS files as well as files that can be distributed to
    minions, such as system configuration files. *See also*: :ref:`Salt's
    file server <file-server>`.

Grain
    A key-value pair which contains a fact about a system, such as its
    hostname, network addresses. *See also*: :ref:`targeting with grains
    <targeting-grains>`.

Highdata
    The data structure in a SLS file the represents a set of state
    declarations. *See also*: :ref:`state layers
    <state-layers-high-data>`.

Highstate
    The collection of states to be applied to a system. *See also*:
    :ref:`state layers <state-layers-highstate>`.

Idempotent
    An action that ensures the system is in a well-known state regardless
    of the system's state before the action is applied.  A corollary to
    this is that applying the action multiple times results in no changes
    to the system.  State module functions should be idempotent.  Some
    state module functions, such as :mod:`cmd.run <salt.states.cmd.run>`
    are not idempotent by default but can be made idempotent with the
    proper use of requisites such as :ref:`unless `
    and :ref:`onlyif <onlyif-requisite>`. For more information, *see*
    `wikipedia <https://en.wikipedia.org/wiki/Idempotent>`_.

Jinja
    A templating language which allows variables and simple logic to be
    dynamically inserted into static text files when they are rendered.
    *See also*: :py:mod:`Salt's Jinja documentation
    <salt.renderers.jinja>`.

Job
    The complete set of tasks to be performed by the execution of a Salt
    command are a single job. *See also*: :py:mod:`jobs runner
    <salt.runners.jobs>`.

Job Cache
    A storage location for job results, which may then be queried by a
    salt runner or an external system. May be local to a salt master
    or stored externally.

Job ID
    A unique identifier to represent a given :term:`job <Job>`.  This is often
    shortened to JID.

Low State
    The collection of processed states after requisites and order are
    evaluated. *See also*: :ref:`state layers <state-layers-low-state>`.

Master
    A central Salt daemon from which commands can be issued to listening
    minions.

Masterless
    A minion which does not require a Salt master to operate. All
    configuration is local. *See also*: :conf_minion:`file_client`.

Master Tops
    A system for the master that allows hooks into external systems to
    generate top file data.

Mine
    A facility to collect arbitrary data from minions and store that data
    on the master. This data is then available to all other minions.
    (Sometimes referred to as Salt Mine.) *See also*: :ref:`Salt Mine
    <salt-mine>`.

Minion
    A server running a Salt minion daemon which can listen to commands from
    a master and perform the requested tasks. Generally, minions are
    servers which are to be controlled using Salt.

Minion ID
    A globally unique identifier for a minion. *See also*:
    :conf_minion:`id`.

Multi-Master
    The ability for a minion to be actively connected to multiple Salt
    masters at the same time in high-availability environments.

Node Group
    A pre-defined group of minions declared in the master configuration
    file. *See also*: :ref:`targeting <targeting-nodegroups>`.

Outputter
    A formatter for defining the characteristics of output data from a Salt
    command. *See also*: :ref:`list of outputters <all-salt.output>`.

Peer Communication
    The ability for minions to communicate directly with other minions
    instead of brokering commands through the Salt master. *See also*:
    :ref:`peer communication `.

Pillar
    A simple key-value store for user-defined data to be made available to
    a minion. Often used to store and distribute sensitive data to minions.
    *See also*: :ref:`Pillar <salt-pillars>`, :ref:`list of Pillar
    modules <all-salt.pillars>`.

Proxy Minion
    A minion which can control devices that are unable to run a Salt minion
    locally, such as routers and switches.

PyDSL
    A Pythonic domain-specific-language used as a Salt renderer. PyDSL can
    be used in cases where adding pure Python into SLS files is beneficial.
    *See also*: :py:mod:`PyDSL <salt.renderers.pydsl>`.

Reactor
    An interface for listening to events and defining actions that Salt
    should taken upon receipt of given events. *See also*: :ref:`Reactor
    <reactor>`.

Render Pipe
    Allows SLS files to be rendered by multiple renderers, with each
    renderer receiving the output of the previous. *See also*:
    :ref:`composing renderers <renderers-composing>`.

Renderer
    Responsible for translating a given data serialization format such as
    YAML or JSON into a Python data structure that can be consumed by Salt.
    *See also*: :ref:`list of renderers <all-salt.renderers>`.

Returner
    Allows for the results of a Salt command to be sent to a given
    data-store such as a database or log file for archival. *See also*:
    :ref:`list of returners <all-salt.returners>`.

Roster
    A flat-file list of target hosts. (Currently only used by salt-ssh.)

Runner Module
    A module containing a set of runner functions. *See also*: :ref:`list
    of runner modules <all-salt.runners>`.

Runner Function
    A function which is called by the :command:`salt-run` command and
    executes on the master instead of on a minion. *See also*:
    :term:`Runner Module`.

Salt Cloud
    A suite of tools used to create and deploy systems on many hosted cloud
    providers. *See also*: :ref:`salt-cloud <salt-cloud>`.

Salt SSH
    A configuration management and remote orchestration system that does
    not require that any software besides SSH be installed on systems to be
    controlled.

Salt Thin
    A subset of the normal Salt distribution that does not include any
    transport routines. A Salt Thin bundle can be dropped onto a host and
    used directly without any requirement that the host be connected to a
    network. Used by Salt SSH. *See also*: :py:mod:`thin runner
    <salt.runners.thin>`.

Salt Virt
    Used to manage the creation and deployment of virtual machines onto a
    set of host machines. Often used to create and deploy private clouds.
    *See also*: :py:mod:`virt runner <salt.runners.virt>`.

SLS Module
    Contains a set of :term:`state declarations <State Declaration>`.

State Compiler
    Translates :term:`highdata <Highdata>` into lowdata.

State Declaration
    A data structure which contains a unique ID and describes one or more
    states of a system such as ensuring that a package is installed or a
    user is defined. *See also*: :ref:`highstate structure
    <state-declaration>`.

State Function
    A function contained inside a :term:`state module <State Module>` which
    can manages the application of a particular state to a system. State
    functions frequently call out to one or more :term:`execution modules
    <Execution Module>` to perform a given task.

State Module
    A module which contains a set of state functions. *See also*:
    :ref:`list of state modules <all-salt.states>`.

State Run
    The application of a set of states on a set of systems.

Syndic
    A forwarder which can relay messages between tiered masters. **See
    also**: :ref:`Syndic <syndic>`.

Target
    Minion(s) to which a given salt command will apply. *See also*:
    :ref:`targeting <targeting>`.

Top File
    Determines which SLS files should be applied to various systems and
    organizes those groups of systems into environments. *See also*:
    :ref:`top file <states-top>`, :ref:`list of master top modules
    <all-salt.tops>`.

__virtual__
    A function in a module that is called on module load to determine
    whether or not the module should be available to a minion. This
    function commonly contains logic to determine if all requirements
    for a module are available, such as external libraries.

Worker
    A master process which can send notices and receive replies from
    minions. *See also*:
    :conf_master:`worker_threads`.

Doc Spelling Wordlist (`doc/spelling_wordlist.txt`)

acl
addr
addrs
admin
adminfile
aggr
aix
aliyun
allusers
amazonaws
amd
ami
amiga
apache
apachectl
api
apikey
apikeys
apis
app
apps
aptpkg
arg
args
arn
arp
asg
askdjghsdfjkghwupujasdflkdfklgjsdfjajkghs
atime
augeas
auth
authid
autodeployed
autodoc
autoload
autoloaded
autoruns
autoscale
autosign
awk
aws
backend
backends
backreferences
backrefs
basedir
basedn
basename
basepath
baseurl
baumgartner
bdist
benke
binlog
blockdev
blockdevice
blockdevices
bluetooth
bluetoothd
bluez
borgstrom
boto
botocore
boucha
br
brtfs
bsd
buildmod
buildout
builtin
cacert
cachedir
cachefile
cassandra
catalina
centerville
centos
cer
cfg
cfgfile
cgroup
cgroups
chage
charset
cherrypy
chocolatey
chown
chroot
cidr
cidrs
cli
cloudstack
cloudwatch
cmd
cmdmod
cmp
collatz
compactionstats
conf
config
configfile
configs
confs
conv
cooldown
copyfile
couchdb
cp
cpu
cpus
cpuset
cpushare
cpustats
cputime
cron
crontab
crpytographic
crt
csr
ctl
cwd
cygwin
daemonize
daemontools
darwin
datastore
datastores
dbuser
dd
ddns
debconf
debconfmod
debian
deinstall
delim
delvol
depclean
deps
deregister
desc
deserialize
deserialized
deserializes
deserializing
dest
dev
dhcp
dict
dicts
diff
difflib
diffs
dih
dir
dirs
disableexcludes
disablerepo
disklabel
disklabels
dismod
dissite
distfiles
distro
distros
dists
django
djangoembed
djangomod
dmg
dmidecode
dns
dnsmasq
dnspython
dnsservers
dnsutil
dockerfile
docstring
docstrings
dpkg
drs
dryrun
dst
dumpe
dvh
eauth
ebuild
ec
eclean
eix
elasticache
elb
emacs
emailaddress
enablerepo
endload
enmod
ensite
env
eselect
esky
etcd
eventbus
expr
extfs
facl
facter
failhard
failover
fallback
fifo
fileclient
filedate
filepath
fileserver
filesystem
filesystems
fmt
foo
forcestop
formulae
fqdn
freebsd
freebsdjail
freebsdkmod
freebsdpkg
freebsdports
freebsdservice
freemem
fromrepo
frontend
frontends
fs
fstab
fstat
fstype
ftp
fw
fwmark
fwrule
gb
gce
gemset
gemsets
gentoo
gentoolkit
gentoolkitmod
getfacl
gid
gids
gitfs
github
gitrepos
glanceclient
glazner
glibc
globbing
globexpression
glsa
gluster
glusterfs
gnomedesktop
gnore
gnupg
gogrid
gpg
gpgowner
gpt
grep
groupadd
groupou
guestfs
gunzip
hadoop
haproxy
haproxyconn
hardcoded
hausler
hc
hg
hgfs
hglib
hiera
highdata
highstate
homebrew
hostname
hostnames
htpasswd
http
httpd
https
hw
hypervisor
hypervisors
iam
ie
iface
ima
img
imgadm
incron
incrontab
indices
inet
influxdb
ing
ini
init
initctl
initscript
inline
inlining
inode
inotify
internet
iowait
ip
ipaddr
ipc
ipcidr
ipe
ips
ipset
ipsets
iptables
ipv
ipy
irb
irq
jid
jinja
jod
jouanin
joyent
jquery
json
jsonify
junos
keycontent
keyfile
keyid
keyname
keypair
keypairs
keysize
keyspace
keyspaces
keystoneclient
kiorky
klaassen
kmod
kuan
kvm
kwarg
kwargs
launchctl
launchd
lbn
lchar
ldap
ldapmod
lgname
libcloud
libcloudfuncs
libgit
libguestfs
libreiserfs
libssh
libvirt
lifecycle
lightdm
linode
linux
loadbalancer
localemod
localfiles
localhost
localtime
logfile
logrotate
logstash
loopback
lowdata
lowstate
lsblk
lspci
lstat
lua
lucene
lv
lvm
lvname
lvs
lxc
lxcbr
lxcutils
macos
macports
mailq
makeconf
makedirs
mako
manpage
manpages
masterless
maxproc
md
mdadm
mem
memcache
memcached
metadata
minion
minionfs
mirrorlist
mkfile
mkfs
mklabel
mknod
mkpart
mkpartfs
mnt
modjk
modprobe
mongo
mongodb
monit
moosefs
mountpoint
msc
msdos
msg
msgpack
mtime
mtree
multicore
multiline
multipart
munin
mutex
mydisk
myinstance
myminion
mynet
myprofile
mysql
mysqldb
nagios
nameserver
nameservers
namespace
namespacing
nano
nbd
netaddr
netapi
netbsd
netbsdservice
netmask
netstat
netstats
networkid
nfs
nftables
ng
nginx
nic
nitty
nocache
nocerts
nodegroup
nodegroups
nodetool
nolimit
noop
notasecret
novaclient
nox
npm
ntp
num
offline
ohai
ok
omapi
online
onlyif
openbsdpkg
openbsdservice
opennebula
openssl
openstack
opensuse
org
originalfile
orm
os
osxdesktop
ou
outlier
outputter
outputters
overlayfs
overstatestage
packageroot
packagesite
pacman
pagerduty
pam
param
paramiko
params
partprobe
passin
passphrase
passthrough
passwd
passwordless
patchfile
pc
pcre
pecl
pecls
pem
perl
pgroup
phar
php
pid
pidfile
pids
pkcs
pkgadd
pkgin
pkgng
pkgrepo
pkgrm
pkgs
pkgutil
pki
plaintext
plist
plugin
plugins
portfetch
postgis
postgres
postgresql
poudriere
poweroff
powerpath
powershell
ppa
pprint
pre
prepend
prepended
preseed
preseeded
preseeding
priv
privkey
proc
processlist
programmatically
proxmox
proxying
ps
psycopg
pubkey
pw
py
pybluez
pycassa
pycrypto
pydsl
pygerduty
pygit
pymongo
pyobjects
pyopenssl
pypureomapi
pysqlite
pysvn
pytest
pythoncom
pythonic
pyvenv
pywintypes
pyyaml
qa
qcow
qemu
queueinfoitem
quickstart
quotastats
qux
rabbitmq
rabbitmqctl
rackconnect
rackspace
rada
radek
rar
rbenv
rc
rdma
rdoc
rdp
readme
realserver
rebase
receipthandle
reclass
redhat
redis
redismod
refactored
refspecs
regen
regex
reinstallation
reiserfs
renderer
renderers
repl
repo
repos
repr
req'd
requestdata
resolv
resourcename
resourcepool
restorable
resync
ret
retcode
returncode
reusability
rh
rhel
ri
riak
rolconnlimit
rolename
rolname
rootfs
rootswinrepo
rootswinrepowinrepo
rsa
rsync
rsyslogd
rubygems
runas
runlevel
rvm
saltcloud
saltcloudmod
saltenv
saltfile
saltify
saltnado
saltstack
saltutil
sbin
schemas
screensaver
scriptlet
scriptlets
sd
sda
sdk
secgroup
securestart
securitygroup
sed
selinux
serializable
serializer
serializers
serverdensity
serverless
servermanager
servlet
setquota
sfdisk
sfn
sha
shas
sid
simplejson
sleekxmpp
sls
smartos
smf
sms
smtp
sockstat
softirq
softlayer
softwareupdate
solaris
solarispkg
solr
someuser
sql
sqlalchemy
sqlite
sqs
src
srv
ssl
stateconf
stderr
stdin
stdout
str
strftime
subfolder
subjectaltname
subjectaltnames
subkeys
subnet
subqueries
sudo
sudoers
superblock
supervisorctl
supervisord
svcs
svn
svnfs
swiftclient
symlink
symlinks
syncdb
syndic
sysadmin
sysadmins
sysbench
sysctl
syslog
sysmod
systemctl
systemd
systemwide
sysupgrade
sysv
sysvinit
syu
tablespace
tarball
tbz
tcp
templating
testrb
tgt
tgz
tibor
timeframe
timespec
tls
tmp
tmpfs
tmux
todo
topfiles
tpstats
traceback
tracebacks
traceroute
trunc
twilio
txt
ubuntu
udp
ui
uid
uids
un
undeploy
unhold
uninstall
uninstallation
uninstalled
uninstalling
uninstalls
unix
unmerge
unmonitor
unpair
unpriv
unrar
unserialize
unsets
unversioned
uri
uris
url
urlencoded
useradd
username
usr
util
utils
utmp
uuids
uwsgi
uzip
vagrantfile
varnishd
vcpus
vdev
venafi
vendored
venv
ver
vg
vgname
vhost
vhosts
vim
vimrc
virt
virtkey
virtualenv
virtualhost
virtualization
vm
vmadm
vms
vmware
vnc
voltype
vpc
vsphere
vt
vtype
vvvvv
walkthrough
warnquota
webapp
webapps
webhook
webserv
webserver
websockets
webutil
wempy
whitelist
wildcard
winreg
winrepo
wmi
worldcompany
writability
ws
wsgi
www
xapi
xcode
xen
xml
xmpp
yaml
yamlex
yamlify
yann
yumpkg
yy
zabbix
zc
zcbuildout
zeromq
zfs
znc
zpool
zsh
zypper


Agents Docs Architecture (`agents/docs/architecture.md`)

Salt Architecture

What is Salt?

Salt is a Python-based configuration management system using a master-minion architecture:

  • Master: Central server that manages configuration and sends commands
  • Minion: Agent running on managed systems that executes commands
  • Event Bus: Real-time communication system between components
  • Loader System: Dynamic plugin system for extending functionality

Module Types

Salt uses a loader system to discover and load different types of modules:

Execution 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 operations
  • salt/modules/cmd.py - Command execution
  • salt/modules/systemd_service.py - systemd service management

State Modules (`salt/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 states
  • salt/states/file.py - File management states
  • salt/states/service.py - Service management states

Runner Modules (`salt/runners/`)

Master-side operations (e.g., salt-run jobs.list_jobs). Runners execute on the Salt master.

Wheel Modules (`salt/wheel/`)

Master configuration management (key management, config). Used for managing the Salt master itself.

Grain Modules (`salt/grains/`)

Static system information collection. Grains provide facts about the minion system (OS, CPU, memory, etc.).

Pillar Modules (`salt/pillar/`)

Dynamic configuration data backends. Pillars provide secure, targeted data to minions.

Beacon Modules (`salt/beacons/`)

System monitoring triggers (watch for events). Beacons monitor system events and fire events on the event bus.

Engine Modules (`salt/engines/`)

Long-running processes on master or minion. Engines provide persistent functionality.

Returner Modules (`salt/returners/`)

Store or send command output to external systems (databases, message queues, etc.).

Renderer Modules (`salt/renderers/`)

Template engines (Jinja, Mako, YAML, JSON). Renderers process state files.

Matcher Modules (`salt/matchers/`)

Target matching (glob, pcre, grain, pillar, compound). Matchers determine which minions execute commands.

Utility Modules (`salt/utils/`)

Shared utility functions (170+ modules). Utilities provide common functionality across Salt.

Directory Structure

text
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

Key Architectural Components

State Compiler

salt/state.py compiles YAML/Jinja templates into execution chunks. Uses NetworkX for dependency graph management with requisites:

  • require: Must run after
  • watch: Run if watched state changes
  • onchanges: Run only if watched state changes
  • onfail: Run if watched state fails
  • listen: Listen for notifications
  • prereq: Run before (with test mode check)

All state operations are idempotent and support test mode (test=True).

Transport Layer

salt/transport/ handles communication between master and minions:

  • ZeroMQ (default): High-performance messaging
  • TCP: Alternative transport
  • WebSocket: For browser-based access

Security

  • PKI-based authentication (salt/crypt.py)
  • AES encryption for all payloads
  • Master key acceptance workflow prevents unauthorized access
  • External auth (eauth) for Salt API access

Event Bus

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 started
  • salt/job/<jid>/ret/<minion_id> - Job return from minion
  • salt/auth - Authentication events
  • salt/minion/<minion_id>/start - Minion started

Loader System

The loader system (salt/loader/) dynamically discovers and loads modules at runtime. Key features:

  • LazyLoader: Loads modules on first access, not import
  • Virtual names: Modules can override their name via __virtual__()
  • Dunder injection: Injects __salt__, __opts__, __grains__, etc.
  • Caching: Modules are cached after first load

Async/Await Transition

Salt is transitioning from Tornado coroutines to native asyncio:

  • Use native async/await syntax, not @tornado.gen.coroutine
  • Prefer asyncio patterns over Tornado patterns
  • Be aware of mixed async code during transition

Master-Minion Communication

  1. Minion authenticates with master via PKI
  2. Master accepts minion key
  3. Minion connects to master on port 4506 (request server)
  4. Master publishes commands on port 4505 (publish server)
  5. Minions subscribe to master's publish port
  6. Commands are encrypted with AES
  7. Results return via request server

File Server

Salt includes a file server that serves files to minions:

  • salt:// URLs reference files on the file server
  • Multiple backends: local, git, S3, HTTP, etc.
  • Files are cached on minions

For details on the Git backends and performance, see GitFS Providers.

Targeting

Minions can be targeted in multiple ways:

  • Glob: *, web*.example.com
  • Grain: os:Ubuntu, kernel:Linux
  • Pillar: role:webserver
  • Compound: G@os:Ubuntu and webserver*
  • List: web1,web2,web3
  • PCRE: Regular expressions

Performance Considerations

Lazy Loading

Modules only load on first access. Import-time side effects may not occur until first use of a module function.

Context Caching

Use __context__ to cache expensive operations within a Salt run (single execution).

Module Discovery

  • Module directories need __init__.py
  • Filename becomes namespace: salt/modules/pkg.py → pkg.*
  • Use __virtualname__ for different name than filename
  • Performance tip: Filename should match virtualname when possible

Additional Resources

Documentation

  • Module development: doc/topics/development/modules/developing.rst
  • State writing guide: doc/ref/states/writing.rst
  • Contributing guidelines: CONTRIBUTING.rst

Example Modules

  • Simple execution module: salt/modules/test.py
  • Complex execution module: salt/modules/file.py
  • Package manager: salt/modules/aptpkg.py, salt/modules/yumpkg.py
  • Service manager: salt/modules/systemd_service.py
  • Simple state: salt/states/pkg.py
  • Complex state: salt/states/file.py

Agents Docs Development Setup (`agents/docs/development-setup.md`)

Salt Development Environment Setup

This guide covers setting up your local development environment for Salt development.

Virtual Environment Requirements

Salt development requires setting up two virtual environments:

  • venv310 (Python 3.10): For running tests on 3006.x and 3007.x branches
  • venv314 (Python 3.14): For running tests on master branch AND running pre-commit hooks

Prerequisites

  • Python 3.10 and Python 3.14 installed on your system
  • Git repository cloned
  • Internet connection for downloading dependencies

Setup venv310 (Python 3.10)

This environment is used for testing on 3006.x and 3007.x branches.

bash
# Create virtual environment
python3.10 -m venv venv310

# Activate
source venv310/bin/activate

# Upgrade pip
pip install --upgrade pip setuptools wheel

# Install platform-specific dependencies (choose your OS)
# Linux:
pip install -r requirements/static/pkg/py3.10/linux.lock

# macOS:
pip install -r requirements/static/pkg/py3.10/darwin.lock

# Windows:
pip install -r requirements/static/pkg/py3.10/windows.lock

# Install pytest requirements
pip install -r requirements/pytest.txt

# Install Salt in editable mode
pip install -e .

# Install tools dependencies (for using tools/ commands)
pip install -r requirements/static/ci/py3.10/tools.lock

# Install pre-commit and python-tools-scripts
pip install pre-commit python-tools-scripts

# Deactivate
deactivate

Setup venv314 (Python 3.14)

This environment is used for testing on master branch and running pre-commit hooks.

bash
# Create virtual environment
python3.14 -m venv venv314

# Activate
source venv314/bin/activate

# Upgrade pip
pip install --upgrade pip setuptools wheel

# Install platform-specific dependencies (choose your OS)
# Linux:
pip install -r requirements/static/pkg/py3.14/linux.lock

# macOS:
pip install -r requirements/static/pkg/py3.14/darwin.lock

# Windows:
pip install -r requirements/static/pkg/py3.14/windows.lock

# Install pytest requirements
pip install -r requirements/pytest.txt

# Install Salt in editable mode
pip install -e .

# Install tools dependencies
pip install -r requirements/static/ci/py3.14/tools.lock

# Install pre-commit and python-tools-scripts
pip install pre-commit python-tools-scripts

# Install pre-commit hooks
pre-commit install

# Deactivate
deactivate

Environment Usage

venv310 is used for:

  • Running tests on 3006.x and 3007.x branches
  • Direct pytest execution on older branches
  • Tools commands (python -m tools)

venv314 is used for:

  • Running tests on master branch
  • Running pre-commit hooks
  • Code formatting and linting checks
  • Pre-commit validation before commits

Verify Installation

bash
# Test Salt import (master / default dev)
./venv314/bin/python -c "import salt.version; print(salt.version.__version__)"

# Run a simple test
./venv314/bin/pytest tests/pytests/unit/test_loader.py -v

# Test tools (3006.x/3007.x workflow)
./venv310/bin/python -m tools --help

IMPORTANT: Using Virtual Environments

When running tests or tools, always use the full path to the venv executable or activate the venv first. This ensures you're using the correct Python environment with all dependencies installed.

Good examples:

bash
./venv310/bin/pytest tests/pytests/unit/test_foo.py -v
./venv314/bin/pre-commit run --files salt/loader/lazy.py
./venv310/bin/python -m tools ts pytest run tests/pytests/unit/

Alternatively, activate first:

bash
source venv314/bin/activate
pytest tests/pytests/unit/test_foo.py -v
deactivate

Troubleshooting

ModuleNotFoundError: No module named 'ptscripts'

If you see this error when running python -m tools, you need to install the tools dependencies:

bash
./venv310/bin/pip install -r requirements/static/ci/py3.10/tools.lock
./venv310/bin/pip install python-tools-scripts

venv not found

If you get "No such file or directory" for venv paths, make sure you've created the virtual environment and are running commands from the repository root directory.

Permission errors

On some systems you may need to use python3.10 and python3.14 explicitly instead of just python3.

Pre-commit hooks not running

Make sure you've run pre-commit install in the venv314 environment:

bash
source venv314/bin/activate
pre-commit install
deactivate

Agents Docs Git And Ci (`agents/docs/git-and-ci.md`)

Git Workflow and CI

Commit Guidelines

CRITICAL RULES

  1. NO attribution lines - NEVER add "Generated with Claude Code", "Co-Authored-By: Claude", or any AI attribution
  2. Use imperative mood - "Fix bug", not "Fixed bug" or "Fixes bug"
  3. Reference issues - Use #NNNN to reference GitHub issues
  4. Small, focused commits - One logical change per commit
  5. Rebase before push - Keep history linear and clean

Good Commit Message Example

text
Fix loader cache invalidation on module reload

When modules are reloaded, the loader cache was not properly
invalidated, causing stale references. Clear the cache dict
on reload to ensure fresh module imports.

Fixes #12345

Bad Commit Message Example

text
Fixed some bugs

Co-Authored-By: Claude <[email protected]>

Why this is bad:

  • Past tense instead of imperative mood
  • Vague description
  • Contains AI attribution (NEVER do this)

PR Workflow

Finding and Checking PRs

bash
# Find PR by branch name
gh pr list --repo saltstack/salt --head <BRANCH-NAME> --limit 5

# Check PR status
gh pr view <PR-NUMBER> --repo saltstack/salt
gh pr checks <PR-NUMBER> --repo saltstack/salt

# Watch CI run
gh run watch <RUN-ID> --repo saltstack/salt

Branch Strategy

  • Main PR branch: master (not main)
  • Release branches: 3006.x, 3007.x, etc.
  • Merge-forward branches: merge/3007.x/master-YY-MM-DD

CI Failure Reproduction

When CI tests fail, you can reproduce the exact failure locally using containers.

Prerequisites

  • Docker installed and running
  • Virtual environment setup (see development-setup.md)
  • ptscripts installed (pip install python-tools-scripts)

Step 1: Download CI Artifacts

First, get the CI artifacts from the failed run:

bash
./venv310/bin/python -m ptscripts ci download-artifacts --run-id <RUN-ID>

The run ID can be found in the GitHub Actions URL or via gh run list.

Step 2: Create Container

Create a container using the same image as CI:

bash
./venv310/bin/python -m ptscripts container create <IMAGE> --name <NAME>
docker start <NAME>

Example container images:

  • ghcr.io/saltstack/salt-ci-containers/testing:debian-11
  • ghcr.io/saltstack/salt-ci-containers/testing:ubuntu-22.04
  • ghcr.io/saltstack/salt-ci-containers/testing:ubuntu-24.04
  • ghcr.io/saltstack/salt-ci-containers/testing:rockylinux-8
  • ghcr.io/saltstack/salt-ci-containers/testing:rockylinux-9
  • ghcr.io/saltstack/salt-ci-containers/testing:fedora-40
  • ghcr.io/saltstack/salt-ci-containers/testing:amazonlinux-2
  • ghcr.io/saltstack/salt-ci-containers/testing:amazonlinux-2023
  • ghcr.io/saltstack/salt-ci-containers/testing:photonos-3
  • ghcr.io/saltstack/salt-ci-containers/testing:photonos-4
  • ghcr.io/saltstack/salt-ci-containers/testing:photonos-5

Step 3: Setup Container

bash
# Decompress dependencies
docker exec <NAME> python3 -m nox -e decompress-dependencies -- linux x86_64

# Create relenv toolchain symlink (Python 3.14+ only)
docker exec <NAME> bash -c "mkdir -p /root/.local/relenv && ln -sf /root/.cache/relenv/toolchains /root/.local/relenv/toolchain"

Step 4: Run Tests

bash
docker exec <NAME> python3 -m nox -e ci-test-onedir -- <TEST-PATH> --run-slow -x -v

Examples:

bash
# Run specific test file
docker exec mycontainer python3 -m nox -e ci-test-onedir -- tests/pytests/unit/modules/test_pkg.py --run-slow -x -v

# Run specific test function
docker exec mycontainer python3 -m nox -e ci-test-onedir -- tests/pytests/unit/modules/test_pkg.py::test_install --run-slow -x -v

# Run with pattern matching
docker exec mycontainer python3 -m nox -e ci-test-onedir -- tests/pytests/unit/ -k test_systemd --run-slow -x -v

Step 5: Debug in Container

If you need to debug interactively:

bash
# Shell into container
docker exec -it <NAME> bash

# Inside container, activate environment and run tests
cd /salt
python3 -m nox -e ci-test-onedir -- tests/pytests/unit/test_foo.py -x -v

Step 6: Cleanup

bash
# Stop and remove container
docker stop <NAME>
docker rm <NAME>

# Clean artifacts
rm -rf artifacts/ nox-*.zip nox.*.tar.*

Container Filesystem Behavior

When testing in containers, be aware:

  • Changes to salt/ source are visible immediately (mounted volume)
  • Changes to Salt library may need artifact refresh:
    bash
    docker exec <NAME> cp /salt/salt/modules/foo.py \
        /salt/artifacts/salt/lib/python3.14/site-packages/salt/modules/

Stale Artifacts

Always clean before downloading new CI artifacts:

bash
rm -rf artifacts/ nox-*.zip nox.*.tar.*

Old artifacts can cause confusing test failures.

Common CI Issues

Tests Pass Locally But Fail in CI

Possible causes:

  1. Different Python version - CI uses specific Python versions per branch
  2. Platform differences - CI runs on Linux, you might be on macOS/Windows
  3. Missing dependencies - CI containers have exact dependency versions
  4. Timing issues - CI environment may be slower/faster
  5. Stale artifacts - Clean and re-download

Container Setup Fails

If dependency decompression fails:

  1. Check you downloaded artifacts for correct run ID
  2. Ensure Docker has enough disk space
  3. Try removing old containers and images

Relenv Toolchain Issues

For Python 3.14+ containers, you must create the symlink:

bash
docker exec <NAME> bash -c "mkdir -p /root/.local/relenv && ln -sf /root/.cache/relenv/toolchains /root/.local/relenv/toolchain"

This is a known path mismatch between relenv versions.

Using MCP Server for CI Workflows

The agents/mcp/salt_test MCP server provides tools for discovering CI failures:

  • ci_pr_failures - Get all failing tests from a PR
  • ci_run_failures - Get failures from specific CI run
  • ci_failure_summary - Get summary of recent failures

See agents/mcp/salt_test/README.md for details.

Best Practices

  1. Always clean artifacts before downloading new ones
  2. Use exact CI container images for reproduction
  3. Note Python version - use venv310 for 3006.x/3007.x, venv314 for master
  4. Check run logs in GitHub Actions for exact command that failed
  5. Test locally first before pushing to avoid CI churn
  6. Keep commits small for easier review and debugging

Agents Docs Module Templates (`agents/docs/module-templates.md`)

Salt Module Templates

This document provides comprehensive templates for writing Salt modules.

Execution Module Template

All execution modules follow this basic structure:

python
"""
Module docstring explaining purpose
"""

import logging

import salt.exceptions
import salt.utils.args
import salt.utils.data
import salt.utils.files
import salt.utils.path
import salt.utils.platform

# Set up logging
log = logging.getLogger(__name__)

# Module metadata
__virtualname__ = "mymodule"  # Optional: override module name
__proxyenabled__ = ["*"]  # Optional: enable for proxy minions
__func_alias__ = {
    "list_": "list"  # Optional: map function names to avoid Python keywords
}


def __virtual__():
    """
    Only load this module if requirements are met
    Returns True, False, or (False, reason)
    """
    if not salt.utils.path.which("mycommand"):
        return False, "mycommand binary not found"
    return True


def my_function(name, param=None):
    """
    Function description

    name
        Description of name parameter

    param
        Description of param parameter

    CLI Example:

    .. code-block:: bash

        salt '*' mymodule.my_function foo param=bar
    """
    log.debug("Running my_function with name=%s", name)

    # Implementation
    result = do_something(name, param)

    return result

State Module Template

State modules provide idempotent, declarative configuration. They call execution modules to do the actual work.

State Return Structure

Every state function MUST return this exact structure:

python
ret = {
    "name": name,        # The name parameter passed to the state
    "result": result,    # True (success), False (failure), or None (test mode)
    "changes": {},       # Dictionary of changes made
    "comment": comment   # String or list describing what happened
}

Complete State Template

text
/* Detailed source-code truncated for AI context efficiency. */

State Flow Diagram

text
1. Validate Input → Invalid? Return with result=False
                  ↓
2. Check Current State
                  ↓
3. Already Correct? → Yes: Return with result=True, no changes
                  ↓ No
4. Test Mode? → Yes: Return with result=None, proposed changes
                  ↓ No
5. Make Changes
                  ↓
6. Verify Changes
                  ↓
7. Return Result (True/False) with changes dict

State Result Values

  • result=True: State succeeded, system is in desired state
  • result=False: State failed, system is NOT in desired state
  • result=None: Test mode, changes would be made but weren't

Changes Dictionary

The changes dictionary should show what changed:

python
# Simple change
ret["changes"] = {"old": "foo", "new": "bar"}

# Multiple changes
ret["changes"] = {
    "user": {"old": "root", "new": "apache"},
    "mode": {"old": "0644", "new": "0755"},
}

# New resource created
ret["changes"] = {"created": name}

# Resource removed
ret["changes"] = {"removed": name}

The __virtual__ Function Patterns

The __virtual__() function determines whether a module should load on a particular system. It runs before any other module code and should be fast.

Return Values

  1. True: Load module with filename as name
  2. False: Don't load module
  3. (False, reason): Don't load, with explanation
  4. "string": Load module with this name (virtualname)
  5. ("string", reason): Load with name, with explanation

Pattern 1: Simple Platform Check

python
def __virtual__():
    """
    Only work on POSIX-like systems
    """
    if salt.utils.platform.is_windows():
        return (
            False,
            "The file execution module cannot be loaded: only available on "
            "non-Windows systems - use win_file instead.",
        )
    return True

Pattern 2: Virtual Name with OS Check

Used when multiple modules implement the same interface (e.g., pkg for different package managers).

python
__virtualname__ = "pkg"

def __virtual__():
    """
    Confirm this module is on a Debian-based system
    """
    if __grains__.get("os_family") == "Debian":
        return __virtualname__
    return False, "The pkg module could not be loaded: unsupported OS family"

Pattern 3: Binary Availability Check

python
def __virtual__():
    """
    Only load if systemctl is available
    """
    if not salt.utils.path.which("systemctl"):
        return False, "The systemd module could not be loaded: systemctl not found"
    return True

Pattern 4: Complex Multi-Condition Check

python
__virtualname__ = "service"

def __virtual__():
    """
    Only work on systems that have been booted with systemd
    """
    is_linux = __grains__.get("kernel") == "Linux"
    is_booted = salt.utils.systemd.booted(__context__)
    is_offline = salt.utils.systemd.offline(__context__)

    if is_linux and (is_booted or is_offline):
        return __virtualname__

    return (
        False,
        "The systemd execution module failed to load: only available on Linux "
        "systems which have been booted with systemd.",
    )

Pattern 5: Check for Execution Module Availability

Used in state modules to verify required execution modules exist.

python
def __virtual__():
    """
    Only make these states available if a pkg provider has been detected
    """
    if "pkg.install" in __salt__:
        return True
    return (False, "pkg module could not be loaded")

Best Practices for __virtual__

  • Keep __virtual__() fast - it runs on every module scan
  • Provide clear error messages explaining why the module didn't load
  • Use salt.utils.platform for platform detection
  • Check grains for OS-specific logic
  • Cache expensive checks in __context__ if needed

Common Module Patterns

Decorators

Salt provides decorators for common tasks:

python
from salt.utils.decorators import depends, memoize
from salt.utils.decorators.path import which

# Ensure binary exists
@which("systemctl")
def restart_service(name):
    """Only available if systemctl is found"""
    pass

# Ensure Python module exists
@depends("docker")
def list_containers():
    """Only available if docker module is installed"""
    pass

# Memoize expensive operations
@memoize
def get_system_info():
    """Cache result for lifetime of process"""
    pass

Function Aliases

Map function names to avoid Python keywords:

python
__func_alias__ = {
    "list_": "list",      # my_module.list() → my_module.list_()
    "exec_": "exec",      # my_module.exec() → my_module.exec_()
}

Cross-Calling Modules

python
def my_function():
    """Call other execution modules"""
    # Get file contents
    content = __salt__["file.read"]("/etc/hosts")

    # Run a command
    output = __salt__["cmd.run"]("ls -la")

    # Install a package
    result = __salt__["pkg.install"]("nginx")

    return result

Argument Handling

python
import salt.utils.args

def my_function(*args, **kwargs):
    """Handle various argument formats"""
    # Clean extra kwargs from state data
    kwargs = salt.utils.args.clean_kwargs(**kwargs)

    # Parse key=value arguments
    kwargs.update(salt.utils.args.parse_input(args))

    return kwargs

Path Handling

python
import salt.utils.path

def my_function():
    """Handle paths safely"""
    # Find binary in PATH
    binary = salt.utils.path.which("nginx")
    if not binary:
        return False

    # Join paths correctly for OS
    config_path = salt.utils.path.join("/etc", "nginx", "nginx.conf")

    return config_path

Platform Detection

python
import salt.utils.platform

def my_function():
    """Handle platform differences"""
    if salt.utils.platform.is_windows():
        return "C:\\Windows"
    elif salt.utils.platform.is_linux():
        return "/etc"
    elif salt.utils.platform.is_darwin():
        return "/Library"

    # Check specific OS family
    if __grains__.get("os_family") == "Debian":
        return "apt"
    elif __grains__.get("os_family") == "RedHat":
        return "yum"

Context Caching Pattern

python
def _get_cached_value():
    """Safe context usage for standalone calls"""
    try:
        context = __context__
    except NameError:
        context = {}

    if "my_key" not in context:
        context["my_key"] = expensive_operation()
    return context.get("my_key")

Error Handling

Use Salt's exception classes for consistent error handling:

python
from salt.exceptions import (
    CommandExecutionError,    # Command/operation failed
    SaltInvocationError,      # Bad function arguments
    MinionError,              # General minion error
    CommandNotFoundError,     # Binary not found
)

def my_function(path, required_param):
    """
    Example with proper error handling
    """
    # Validate required parameters
    if not required_param:
        raise SaltInvocationError("required_param is mandatory")

    # Validate parameter values
    if not os.path.exists(path):
        raise SaltInvocationError(f"Path does not exist: {path}")

    # Check for required binary
    binary = salt.utils.path.which("mytool")
    if not binary:
        raise CommandNotFoundError("mytool binary not found in PATH")

    # Execute operation with error handling
    try:
        result = __salt__["cmd.run_all"](f"{binary} {path}")
    except Exception as exc:
        raise CommandExecutionError(
            f"Failed to run mytool on {path}: {exc}"
        )

    # Check command result
    if result["retcode"] != 0:
        raise CommandExecutionError(
            f"mytool failed: {result['stderr']}"
        )

    return result["stdout"]

When to Use Each Exception

  • SaltInvocationError: Invalid function arguments, missing required parameters
  • CommandExecutionError: Operation failed (file not found, command failed, etc.)
  • CommandNotFoundError: Required binary not in PATH
  • MinionError: General minion-side errors
  • Standard exceptions: Use Python's built-in exceptions when appropriate

Module Checklists

Execution Module Checklist

  • Proper imports (logging, salt.exceptions, salt.utils.*)
  • Logger configured: log = logging.getLogger(__name__)
  • __virtual__() function if platform/dependency specific
  • Docstrings on all functions with CLI examples
  • Input validation with proper exceptions
  • Error handling with CommandExecutionError/SaltInvocationError
  • Use __context__ for caching expensive operations
  • Unit tests covering success and error cases

State Module Checklist

  • Returns correct dict structure (name, result, changes, comment)
  • Validates input parameters
  • Checks current state before making changes
  • Handles test mode (__opts__["test"])
  • Verifies changes after applying
  • Sets result correctly (True/False/None)
  • Populates changes dict with before/after
  • Provides clear comment explaining what happened

Reference Files

  • Simple example: salt/modules/test.py
  • Complex example: salt/modules/file.py
  • Platform-specific: salt/modules/aptpkg.py, salt/modules/systemd_service.py
  • State examples: salt/states/file.py, salt/states/pkg.py
  • Documentation: doc/topics/development/modules/developing.rst, doc/ref/states/writing.rst

Agents Docs Package Building (`agents/docs/package-building.md`)

Package Building Guide

This guide describes how to build Salt packages (RPM, Deb, etc.) locally using the same methods as the CI/CD pipeline.

Overview

Salt packages are built using the tools script (specifically tools pkg) running inside a CI container. This ensures the build environment matches the official release environment.

The general process is:

  1. Enter the appropriate CI container
  2. Setup the Python environment
  3. Build the source tarball
  4. Build the "Onedir" (a self-contained directory with Python and dependencies)
  5. Build the final package (RPM/Deb) using the Onedir

Prerequisites

  • Docker installed and running
  • python-tools-scripts installed in your local environment (optional, but helpful for some commands)

Reference Workflows

The instructions in this guide are derived from the official GitHub Actions workflows. If you need to verify the current build process or versions, check these files:

  • .github/workflows/ci.yml: The main entry point for CI builds. It defines the high-level orchestration.
  • .github/workflows/build-salt-onedir.yml: Defines how the "Onedir" (relocatable Python environment) is built. Check this for relenv and python versions.
  • .github/workflows/build-packages.yml: Defines how the final RPM/Deb/Windows/macOS packages are built using the Onedir.
  • .github/actions/build-source-tarball/action.yml: The steps to create the initial source distribution.

Building RPMs (Linux)

1. Enter the Build Container

From the root of the Salt repository:

bash
docker run --rm -it \
  -v "$(pwd):/salt" \
  -w /salt \
  ghcr.io/saltstack/salt-ci-containers/testing:fedora-42 \
  bash

Note: Use fedora-42 for RPM builds. For Deb builds, use debian-11 or similar.

2. Setup Python Environment (Inside Container)

Once inside the container:

bash
# Detect python version (likely 3.10 or 3.14 depending on branch/container)
PY_VER=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")

# Create and activate venv
python3 -m venv venv
source venv/bin/activate

# Install build dependencies
pip install --upgrade pip setuptools
pip install -r requirements/static/ci/py${PY_VER}/tools.lock
pip install -e .

3. Build Source Tarball

Create the source distribution:

bash
python3 -m tools pkg source-tarball

This will create dist/salt-<version>.tar.gz.

4. Build Salt Onedir

The "Onedir" is an artifact containing Salt and all its dependencies (including Python itself) in a relocatable directory.

bash
# Get the version from the tarball
SALT_VERSION=$(ls dist/salt-*.tar.gz | sed 's/dist\/salt-//;s/.tar.gz//')
mkdir -p artifacts

# Build the Onedir
# Note: CI uses specific pinned versions for relenv and python.
# Check .github/workflows/build-salt-onedir.yml for current versions.
python3 -m tools pkg build salt-onedir "dist/salt-${SALT_VERSION}.tar.gz" \
    --platform linux \
    --package-name artifacts/salt \
    --relenv-version 0.22.4

# Cleanup and Archive
python3 -m tools pkg pre-archive-cleanup artifacts/salt
tar -cJf "artifacts/salt-${SALT_VERSION}-onedir-linux-x86_64.tar.xz" -C artifacts salt

5. Build RPM Package

Use the Onedir artifact to build the final RPM.

bash
python3 -m tools pkg build rpm \
    --relenv-version=0.22.4 \
    --python-version=3.10.19 \
    --onedir="salt-${SALT_VERSION}-onedir-linux-x86_64.tar.xz"

The RPMs will be generated in ~/rpmbuild/RPMS/x86_64/.

6. Retrieve Artifacts

Before exiting the container, copy the RPMs to the mounted volume:

bash
mkdir -p artifacts/rpm
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm artifacts/rpm/

Building DEBs (Linux)

The process is similar to RPMs but uses the deb command and a Debian container.

  1. Use ghcr.io/saltstack/salt-ci-containers/testing:debian-11 (or newer).
  2. Follow steps 2-4 above (Source Tarball & Onedir).
  3. Run python3 -m tools pkg build deb ... instead of rpm.

Building Windows/macOS Packages

Windows and macOS packages are typically built on their respective host OSs in CI, not in Docker containers. Refer to .github/workflows/build-packages.yml for the specific steps and requirements (signing certificates, etc.).


Agents Docs Testing (`agents/docs/testing.md`)

Salt Testing Guide

Salt uses multiple test frameworks. All new code should include tests.

Test Directory Structure

text
tests/
├── unit/               # Fast unit tests (no daemons, heavy mocking)
│   ├── modules/        # Tests for salt/modules/
│   ├── states/         # Tests for salt/states/
│   └── utils/          # Tests for salt/utils/
├── integration/        # Integration tests (with daemons)
│   ├── modules/        # Tests for salt/modules/
│   ├── states/         # Tests for salt/states/
│   └── ...
└── pytests/           # Pytest-based tests (newer style)
    ├── unit/
    ├── integration/
    └── functional/

Unit Test Templates

Legacy Style (TestCase)

python
"""
Tests for salt.modules.mymodule
"""

import pytest

import salt.modules.mymodule as mymodule
from salt.exceptions import CommandExecutionError, SaltInvocationError
from tests.support.mixins import LoaderModuleMockMixin
from tests.support.mock import MagicMock, patch
from tests.support.unit import TestCase


class MyModuleTestCase(TestCase, LoaderModuleMockMixin):
    """
    Test cases for salt.modules.mymodule
    """

    def setup_loader_modules(self):
        """
        Setup loader modules - injects dunders
        """
        return {
            mymodule: {
                "__opts__": {"test": False},
                "__grains__": {"os": "Linux"},
                "__salt__": {},
            }
        }

    def test_simple_function(self):
        """
        Test simple function
        """
        result = mymodule.my_function("test")
        self.assertEqual(result, "expected")

    def test_with_mock(self):
        """
        Test with mocked subprocess call
        """
        mock_cmd = MagicMock(return_value={"retcode": 0, "stdout": "success"})
        with patch.dict(mymodule.__salt__, {"cmd.run_all": mock_cmd}):
            result = mymodule.my_function("test")
            self.assertTrue(result)
            mock_cmd.assert_called_once()

    def test_error_handling(self):
        """
        Test error conditions
        """
        with self.assertRaises(SaltInvocationError):
            mymodule.my_function(None)

Pytest Style (Newer)

python
"""
Tests for salt.modules.mymodule
"""

import pytest

import salt.modules.mymodule as mymodule
from salt.exceptions import SaltInvocationError


@pytest.fixture
def configure_loader_modules():
    """
    Setup module dunders
    """
    return {
        mymodule: {
            "__opts__": {"test": False},
            "__grains__": {"os": "Linux"},
            "__salt__": {},
        }
    }


def test_simple_function():
    """
    Test simple function
    """
    result = mymodule.my_function("test")
    assert result == "expected"


def test_error_handling():
    """
    Test error conditions
    """
    with pytest.raises(SaltInvocationError):
        mymodule.my_function(None)

Mocking Patterns

Basic Mocking

python
from tests.support.mock import MagicMock, patch, call

# Mock a function call
mock_func = MagicMock(return_value="result")
with patch("salt.modules.mymodule.some_function", mock_func):
    result = mymodule.my_function()
    mock_func.assert_called_once_with("expected_arg")

# Mock dunder dict
with patch.dict(mymodule.__salt__, {"cmd.run": MagicMock(return_value="output")}):
    result = mymodule.my_function()

# Mock with side effects
mock_func = MagicMock(side_effect=[
    {"retcode": 1, "stdout": "error"},  # First call fails
    {"retcode": 0, "stdout": "success"},  # Second call succeeds
])
with patch.dict(mymodule.__salt__, {"cmd.run_all": mock_func}):
    result = mymodule.my_function()

Test Best Practices

  1. One test per function behavior: Test success cases, error cases, edge cases separately
  2. Use descriptive test names: test_function_name_when_condition_then_expected_result
  3. Mock external dependencies: File I/O, network calls, subprocess calls
  4. Test error handling: Verify exceptions are raised correctly
  5. Test input validation: Verify bad inputs are rejected
  6. Keep tests fast: Unit tests should run in milliseconds
  7. Don't test implementation details: Test the public API, not internal helpers

Running Tests

bash
# Run all tests
nox -e test-3

# Run specific test file
nox -e test-3 -- tests/pytests/unit/test_loader.py

# Run with pattern matching
nox -e test-3 -- -k test_auth

# Run specific test function
nox -e test-3 -- tests/pytests/unit/test_loader.py::test_load_modules

# Run last failed tests
nox -e test-3 -- --lf

# Run with specific Python version
nox -e test-3.10
nox -e test-3.14

# Run with specific transport
nox -e test-tcp-3
nox -e test-zeromq-3

# Run with coverage
nox -e test-3 --coverage
nox -e coverage-report

Using Virtual Environment (Faster for Development)

If you have a local venv setup:

bash
# Run tests directly with pytest (master branch: use venv312)
./venv312/bin/pytest tests/pytests/unit/test_foo.py::test_bar -v

# Run pre-commit checks on specific files
./venv312/bin/pre-commit run --files salt/loader/lazy.py

Container Testing (Reproduce CI Failures)

To reproduce CI failures locally using the same container environment:

1. Download CI artifacts

bash
./venv310/bin/python -m ptscripts ci download-artifacts --run-id <RUN-ID>

2. Create container

bash
./venv310/bin/python -m ptscripts container create <IMAGE> --name <NAME>
docker start <NAME>

3. Setup container

bash
# Decompress dependencies
docker exec <NAME> python3 -m nox -e decompress-dependencies -- linux x86_64

# Create relenv toolchain symlink (Python 3.14+ only)
docker exec <NAME> bash -c "mkdir -p /root/.local/relenv && ln -sf /root/.cache/relenv/toolchains /root/.local/relenv/toolchain"

4. Run tests

bash
docker exec <NAME> python3 -m nox -e ci-test-onedir -- <TEST-PATH> --run-slow -x -v

Example container images

  • ghcr.io/saltstack/salt-ci-containers/testing:debian-11
  • ghcr.io/saltstack/salt-ci-containers/testing:ubuntu-22.04
  • ghcr.io/saltstack/salt-ci-containers/testing:rockylinux-9

Linting and Formatting

Black (Code Formatting)

bash
# Format all code
black .

# Check without modifying
black --check .

Black uses 88 character line length by default.

isort (Import Sorting)

bash
# Sort all imports
isort .

# Check without modifying
isort --check .

isort is configured with profile 3 and trailing commas in pyproject.toml.

Linting

bash
# Lint both salt and tests
nox -e lint

# Lint Salt code only
nox -e lint-salt

# Lint tests only
nox -e lint-tests

Example Test Files

For reference, see:

  • Unit test example: tests/unit/modules/test_systemd_service.py
  • Complex mocking: tests/unit/modules/test_cron.py
  • Documentation: doc/topics/tutorials/writing_tests.rst

Agents Docs Troubleshooting (`agents/docs/troubleshooting.md`)

Salt Development Troubleshooting

Common gotchas and solutions when developing Salt.

Import Order Issues

Salt enforces strict import order via isort (profile 3, trailing commas). Configuration is in pyproject.toml.

Required Order

python
# 1. Standard library imports
import logging
import os
import sys

# 2. Salt imports
import salt.exceptions
import salt.utils.args
import salt.utils.platform

# 3. Third-party imports
import requests

Fixing Import Order

bash
# Auto-fix import order
isort .

# Check without modifying
isort --check .

Module Discovery Issues

Missing __init__.py

Module directories need __init__.py files for Python to recognize them as packages.

bash
# Check for missing __init__.py
find salt/modules -type d ! -exec test -e {}/__init__.py \; -print

Filename Becomes Namespace

The filename determines the module namespace:

  • salt/modules/pkg.py → accessible as pkg.*
  • Use __virtualname__ to override the name

Performance Tip

Filename should match virtualname when possible to avoid loader overhead.

Good:

python
# File: salt/modules/systemd_service.py
__virtualname__ = "service"  # Will be service.* on systemd systems

Less efficient:

python
# File: salt/modules/my_totally_different_name.py
__virtualname__ = "service"  # Loader has to scan more files

Loader Changes Impact Everything

Changes to salt/loader/ affect all plugin types (modules, states, grains, pillars, etc.).

Test Thoroughly

bash
# Run loader unit tests
nox -e test-3 -- tests/pytests/unit/test_loader.py

# Run integration tests
nox -e test-3 -- tests/pytests/integration/

Common Loader Issues

  1. Cache invalidation - Clear __context__ properly on reload
  2. Dunder injection - Ensure all required dunders are injected
  3. Virtual module loading - Check __virtual__() is called correctly
  4. Lazy loading - Modules only load on first access

ZeroMQ Issues

Tests Hang or Timeout

If tests hang indefinitely:

bash
# Kill stale Salt processes
pkill -9 -f salt

# Check for port conflicts
lsof -i :4505  # Publisher port
lsof -i :4506  # Request port

Verify ZeroMQ Installation

bash
python -c "import zmq; print(zmq.zmq_version())"

If this fails, reinstall ZeroMQ:

bash
pip uninstall pyzmq
pip install pyzmq

Port Conflicts

Salt uses:

  • 4505: Publish port (master publishes commands)
  • 4506: Request port (minions send requests)

If these ports are in use, tests will fail or hang.

Container Filesystem Behavior

When running tests in containers:

Source Changes

Changes to salt/ source code are visible immediately (mounted volume):

bash
# Edit on host
vim salt/modules/pkg.py

# Immediately visible in container
docker exec mycontainer cat /salt/salt/modules/pkg.py

Library Changes

Changes to installed Salt library may need manual sync:

bash
# After editing source, copy to installed location
docker exec <NAME> cp /salt/salt/modules/foo.py \
    /salt/artifacts/salt/lib/python3.14/site-packages/salt/modules/

Python 3.14+ Compatibility

Known Issues

  1. IPv6 timeout - Python 3.14+ prefers IPv6, waits before IPv4 fallback
  2. Relenv toolchain path - Expects /root/.local/relenv/toolchain/, but relenv uses /root/.cache/relenv/toolchains/
  3. "backports" module - Conditionally included in Python < 3.13

Solutions

IPv6 Timeout

Use ULA IPv6 addresses with NAT:

yaml
# In container config
networks:
  default:
    enable_ipv6: true
    ipam:
      config:
        - subnet: fd00:db8::/64

Relenv Toolchain Path

Create symlink in container:

bash
docker exec <NAME> bash -c "mkdir -p /root/.local/relenv && ln -sf /root/.cache/relenv/toolchains /root/.local/relenv/toolchain"

This is required for all Python 3.14+ container tests.

Backports Module

Update test mocks to handle conditional import:

python
# Old (fails on 3.13+)
import backports.ssl

# New (handles both)
try:
    import backports.ssl
except ImportError:
    import ssl as backports_ssl

Stale Artifacts

Symptom

Tests fail with confusing errors like "module not found" or "wrong version".

Solution

Always clean before downloading new CI artifacts:

bash
rm -rf artifacts/ nox-*.zip nox.*.tar.*

Why This Happens

Artifacts are cached locally. If you download artifacts from a different run, old files may conflict.

Lazy Loading Behavior

Issue

Modules only load on first access. Import-time side effects may not occur until first use of a module function.

Example

python
# Module import doesn't execute __virtual__()
import salt.modules.systemd_service

# __virtual__() executes on first function call
salt.modules.systemd_service.restart("nginx")

Impact

  • Unit tests must trigger module loading explicitly
  • Side effects at module level may not happen when expected
  • __virtual__() failures only visible on first use

Pre-commit Hook Issues

Hooks Not Running

If pre-commit hooks don't run on commit:

bash
# Ensure you're in venv314
source venv314/bin/activate

# Install hooks
pre-commit install

# Test manually
pre-commit run --all-files

Hook Failures

If hooks fail:

bash
# Run specific hook
pre-commit run black --all-files
pre-commit run isort --all-files

# Auto-fix issues
black .
isort .

Only skip hooks if absolutely necessary:

bash
git commit --no-verify

Module Import Errors

Salt Exceptions Not Found

If you get ImportError: cannot import name 'SaltInvocationError':

python
# Wrong
from salt.exceptions import SaltInvocationError

# Check spelling and case
from salt.exceptions import (
    CommandExecutionError,
    SaltInvocationError,  # Note: capital I
)

Circular Import Issues

Salt's loader system can sometimes create circular imports. Solutions:

  1. Lazy import - Import inside function instead of module level
  2. Use salt - Call other modules via __salt__ instead of direct import
  3. Utility functions - Move shared code to salt/utils/

Test Failures

Tests Pass Individually But Fail Together

This often indicates:

  1. Shared state - Tests modifying global state
  2. Resource conflicts - Tests using same ports/files
  3. Order dependency - Tests depending on execution order

Solution: Use proper teardown and isolation.

Mocking Doesn't Work

Common issues:

python
# Wrong - mocking after import
import salt.modules.mymodule as mymodule
with patch("some.function"):  # Too late!
    mymodule.my_function()

# Right - mock before use
with patch("salt.modules.mymodule.some_function"):
    import salt.modules.mymodule as mymodule
    mymodule.my_function()

# Better - use patch.dict for dunders
with patch.dict(mymodule.__salt__, {"cmd.run": MagicMock()}):
    mymodule.my_function()

Performance Issues

Slow Tests

If tests are slow:

  1. Check mocking - Ensure external calls are mocked
  2. Avoid network - Mock all network operations
  3. Mock subprocess - Don't run real commands in unit tests
  4. Use context - Cache expensive operations

Slow __virtual__

Keep __virtual__() fast:

python
# Bad - expensive operation
def __virtual__():
    packages = fetch_all_packages()  # Slow!
    if "mypackage" in packages:
        return True
    return False

# Good - quick check
def __virtual__():
    if salt.utils.path.which("mycommand"):
        return True
    return False

Common Error Messages

"Transport ZMQ exception"

  • Kill stale processes: pkill -9 -f salt
  • Check ZeroMQ install: python -c "import zmq"
  • Check port availability: lsof -i :4505 :4506

"Module 'X' could not be loaded"

  • Check __virtual__() return value
  • Verify dependencies are installed
  • Check platform compatibility

"KeyError: '__salt__'"

  • Dunder not injected - check test fixture
  • Module not loaded via loader - use proper test setup

"SaltInvocationError"

  • Check function arguments
  • Validate required parameters are provided
  • Ensure parameter types are correct

Getting Help

If you're still stuck:

  1. Check existing modules - Look for similar patterns
  2. Read test files - See how others test similar code
  3. Git history - Look at how issues were fixed before
  4. Documentation - Check doc/ directory
  5. Contributing guide - Read CONTRIBUTING.rst

Doc Incl Extend With Require Watch (`doc/_incl/extend_with_require_watch.rst`)

.. admonition:: Using extend with require or watch

text
The ``extend`` statement works differently for ``require`` or ``watch``.
It appends to, rather than replacing the requisite component.

Doc Incl Grains Passwords (`doc/_incl/grains_passwords.rst`)

.. warning::

Grains can be set by users that have access to the minion configuration files on
the local system, making them less secure than other identifiers in Salt. Avoid
storing sensitive data, such as passwords or keys, on minions. Instead, make
use of :ref:pillar and/or :ref:sdb.


Doc Incl Jinja Security (`doc/_incl/jinja_security.rst`)

.. important::

:ref:Jinja supports a secure, sandboxed template execution environment <https://jinja.palletsprojects.com/en/2.11.x/sandbox/>__ that Salt
takes advantage of. Other text :ref:renderers do not support this
functionality, so Salt highly recommends usage of jinja / jinja|yaml.


Doc Incl Requisite Incl (`doc/_incl/requisite_incl.rst`)

Before continuing make sure you have a working Salt installation by
following the instructions in the
Salt install guide <https://docs.saltproject.io/salt/install-guide/en/latest/>_.

.. admonition:: Stuck?

text
The Salt Project community can help offer advice and help troubleshoot
technical issues as you're learning about Salt. One of the best places to
talk to the community is on the
`Salt Project Discord Community <https://discord.com/invite/J7b7EscrAs>`_.

Doc Incl Sls Filename Cant Contain Period (`doc/_incl/sls_filename_cant_contain_period.rst`)

.. admonition:: Do not use dots in SLS file names or their directories

text
The initial implementation of :conf_master:`top.sls <state_top>` and
:ref:`include-declaration` followed the python import model where a slash
is represented as a period.  This means that a SLS file with a period in
the name ( besides the suffix period) can not be referenced.  For example,
webserver_1.0.sls is not referenceable because webserver_1.0 would refer
to the directory/file webserver_1/0.sls

The same applies for any subdirectories, this is especially 'tricky' when
git repos are created.  Another command that typically can't render its
output is ```state.show_sls``` of a file in a path that contains a dot.

Doc Static Versions.Json (`doc/_static/versions.json`)

[
{
"name": "Latest (3008)",
"version": "latest",
"url": "https://docs.saltproject.io/en/latest/"
},
{
"name": "3008",
"version": "3008",
"url": "https://docs.saltproject.io/en/3008/"
},
{
"name": "3006",
"version": "3006",
"url": "https://docs.saltproject.io/en/3006/"
},
{
"name": "Master (Dev)",
"version": "master",
"url": "https://docs.saltproject.io/en/master/"
}
]


Doc Ref Index (`doc/ref/index.rst`)

===================== Salt Module Reference

This section contains a list of the Python modules that are used to extend the various subsystems within Salt.

.. toctree::
:maxdepth: 1
:glob:

text
../ref/auth/all/index
../ref/beacons/all/index
../ref/cache/all/index
../ref/clouds/all/index
../ref/engines/all/index
../ref/modules/all/index
../ref/executors/all/index
../ref/file_server/all/index
../ref/grains/all/index
../ref/netapi/all/index
../ref/output/all/index
../ref/pillar/all/index
../ref/proxy/all/index
../ref/queues/all/index
../ref/renderers/all/index
../ref/returners/all/index
../ref/roster/all/index
../ref/runners/all/index
../ref/sdb/all/index
../ref/serializers/all/index
../ref/states/all/index
../ref/thorium/all/index
../ref/tokens/all/index
../ref/tops/all/index
../ref/wheel/all/index

Doc Ref Peer (`doc/ref/peer.rst`)

.. _peer:

================== Peer Communication

Salt 0.9.0 introduced the capability for Salt minions to publish commands. The
intent of this feature is not for Salt minions to act as independent brokers
one with another, but to allow Salt minions to pass commands to each other.

In Salt 0.10.0 the ability to execute runners from the master was added. This
allows for the master to return collective data from runners back to the
minions via the peer interface.

The peer interface is configured through two options in the master
configuration file. For minions to send commands from the master the peer
configuration is used. To allow for minions to execute runners from the master
the peer_run configuration is used.

Since this presents a viable security risk by allowing minions access to the
master publisher the capability is turned off by default. The minions can be
allowed access to the master publisher on a per minion basis based on regular
expressions. Minions with specific ids can be allowed access to certain Salt
modules and functions.

Peer Configuration

The configuration is done under the peer setting in the Salt master
configuration file, here are a number of configuration possibilities.

The simplest approach is to enable all communication for all minions, this is
only recommended for very secure environments.

.. code-block:: yaml

text
peer:
  .*:
    - .*

This configuration allows minions with IDs ending in .example.com access
to the test, ps, and pkg module functions.

.. code-block:: yaml

text
peer:
  .*\.example.com:
    - test\..*
    - ps\..*
    - pkg\..*

The configuration logic is simple, a regular expression is passed for matching
minion ids, and then a list of expressions matching minion functions is
associated with the named minion. For instance, this configuration will also
allow minions ending with foo.org access to the publisher.

.. code-block:: yaml

text
peer:
  .*\.example.com:
    - test\..*
    - ps\..*
    - pkg\..*
  .*\.foo.org:
    - test\..*
    - ps\..*
    - pkg\..*

.. note::
Functions are matched using regular expressions as well.

It is also possible to limit target hosts with the :term:Compound Matcher.
You can achieve this by adding another layer in between the source and the
allowed functions:

.. code-block:: yaml

text
peer:
  '.*\.example\.com':
    - 'G@role:db':
      - test\..*
      - pkg\..*

.. note::

text
Notice that the source hosts are matched by a regular expression
on their minion ID, while target hosts can be matched by any of
the :ref:`available matchers <targeting-compound>`.

Note that globbing and regex matching on pillar values is not supported. You can only match exact values.

Peer Runner Communication

Configuration to allow minions to execute runners from the master is done via
the peer_run option on the master. The peer_run configuration follows
the same logic as the peer option. The only difference is that access is
granted to runner modules.

To open up access to all minions to all runners:

.. code-block:: yaml

text
peer_run:
  .*:
    - .*

This configuration will allow minions with IDs ending in example.com access
to the manage and jobs runner functions.

.. code-block:: yaml

text
peer_run:
  .*example.com:
    - manage.*
    - jobs.*

.. note::
Functions are matched using regular expressions.

Using Peer Communication

The publish module was created to manage peer communication. The publish module
comes with a number of functions to execute peer communication in different
ways. Currently there are three functions in the publish module. These examples
will show how to test the peer system via the salt-call command.

To execute test.version on all minions:

.. code-block:: bash

text
# salt-call publish.publish \* test.version

To execute the manage.up runner:

.. code-block:: bash

text
# salt-call publish.runner manage.up

To match minions using other matchers, use tgt_type:

.. code-block:: bash

text
# salt-call publish.publish 'webserv* and not G@os:Ubuntu' test.version tgt_type='compound'

.. note::
In pre-2017.7.0 releases, use expr_form instead of tgt_type.


Doc Ref Publisheracl (`doc/ref/publisheracl.rst`)

.. _publisher-acl:

==================== Publisher ACL system

The salt publisher ACL system is a means to allow system users other than root
to have access to execute select salt commands on minions from the master.

.. note::

text
``publisher_acl`` is useful for allowing local system users to run Salt
commands without giving them root access. If you can log into the Salt
master directly, then ``publisher_acl`` allows you to use Salt without
root privileges. If the local system is configured to authenticate against
a remote system, like LDAP or Active Directory, then ``publisher_acl`` will
interact with the remote system transparently.

``external_auth`` is useful for ``salt-api`` or for making your own scripts
that use Salt's Python API. It can be used at the CLI (with the ``-a``
flag) but it is more cumbersome as there are more steps involved.  The only
time it is useful at the CLI is when the local system is *not* configured
to authenticate against an external service *but* you still want Salt to
authenticate against an external service.

For more information and examples, see :ref:`this Access Control System
<acl_types>` section.

The publisher ACL system is configured in the master configuration file via the
publisher_acl configuration option. Under the publisher_acl
configuration option the users open to send commands are specified and then a
list of the minion functions which will be made available to specified user.
Both users and functions could be specified by exact match, shell glob or
regular expression. This configuration is much like the :ref:external_auth <acl-eauth> configuration:

.. code-block:: yaml

text
publisher_acl:
  # Allow thatch to execute anything.
  thatch:
    - .*
  # Allow fred to use test and pkg, but only on "web*" minions.
  fred:
    - web*:
      - test.*
      - pkg.*
  # Allow admin and managers to use saltutil module functions
  admin|manager_.*:
    - saltutil.*
  # Allow users to use only my_mod functions on "web*" minions with specific arguments.
  user_.*:
    - web*:
      - 'my_mod.*':
          args:
            - 'a.*'
            - 'b.*'
          kwargs:
            'kwa': 'kwa.*'
            'kwb': 'kwb'

Permission Issues

Directories required for publisher_acl must be modified to be readable by
the users specified:

.. code-block:: bash

text
chmod 755 /var/cache/salt /var/cache/salt/master /var/cache/salt/master/jobs /var/run/salt /var/run/salt/master

.. note::

text
In addition to the changes above you will also need to modify the
permissions of /var/log/salt and the existing log file to be writable by
the user(s) which will be running the commands. If you do not wish to do
this then you must disable logging or Salt will generate errors as it
cannot write to the logs as the system users.

If you are upgrading from earlier versions of salt you must also remove any
existing user keys and re-start the Salt master:

.. code-block:: bash

text
rm /var/cache/salt/.*key
service salt-master restart

Whitelist and Blacklist

Salt's authentication systems can be configured by specifying what is allowed
using a whitelist, or by specifying what is disallowed using a blacklist. If
you specify a whitelist, only specified operations are allowed. If you specify
a blacklist, all operations are allowed except those that are blacklisted.

See :conf_master:publisher_acl and :conf_master:publisher_acl_blacklist.


Doc Ref Python Api (`doc/ref/python-api.rst`)

:orphan:

================= Python client API

.. seealso:: Moved to :ref:client-apis


Doc Security Index (`doc/security/index.rst`)

.. _disclosure:

========================== Security disclosure policy

The canonical Salt security policy, contact information and PGP public key
live in the SECURITY.md file at the root of the Salt source tree.

To avoid this page drifting out of sync with the live document, see:

  • SECURITY.md on master <https://github.com/saltstack/salt/blob/master/SECURITY.md>_

That file is the authoritative source for:

  • the security contact email
  • the current GPG key ID and fingerprint
  • the full ASCII-armored GPG public key
  • the security response procedure

.. _saltstack_security_announcements:

Receiving security announcements

For receiving security announcements, see the SECURITY.md file linked
above. Notifications are sent to the salt-packagers, salt-users and
salt-announce mailing lists.


Doc Topics About Salt Project (`doc/topics/about_salt_project.rst`)

.. _about-salt-project:

============ Salt Project

.. include:: ../../README.rst


Doc Topics Api (`doc/topics/api.rst`)

==== APIs

.. toctree::
:maxdepth: 1

text
../ref/clients/index
netapi/index

Doc Topics Best Practices (`doc/topics/best_practices.rst`)

.. _best-practices:

============================ Salt :index:`Best Practices`

Salt's extreme flexibility leads to many questions concerning the structure of
configuration files.

This document exists to clarify these points through examples and code.

.. important::
The guidance here should be taken in combination with :ref:hardening-salt.

General rules

  1. Modularity and clarity should be emphasized whenever possible.

  2. Create clear relations between pillars and states.

  3. Use variables when it makes sense but don't overuse them.

  4. Store sensitive data in pillar.

  5. Don't use grains for matching in your pillar top file for any sensitive
    pillars.

  6. When accessing modules from within a template, use the mapping
    key syntax instead of the attribute one to avoid edge cases. Example:

    .. code-block:: jinja

    text
    {%- set do_this = salt['pillar.get']('foo:bar') %}
    {%- set avoid_this = salt.pillar.get('foo:bar') %}

    .. include:: ../_incl/grains_passwords.rst

Structuring States and Formulas

When structuring Salt States and Formulas it is important to begin with the
directory structure. A proper directory structure clearly defines the
functionality of each state to the user via visual inspection of the state's
name.

Reviewing the :formula_url:MySQL Salt Formula <mysql-formula>
it is clear to see the benefits to the end-user when reviewing a sample of the
available states:

.. code-block:: bash

text
/srv/salt/mysql/files/
/srv/salt/mysql/client.sls
/srv/salt/mysql/map.jinja
/srv/salt/mysql/python.sls
/srv/salt/mysql/server.sls

This directory structure would lead to these states being referenced in a top
file in the following way:

.. code-block:: yaml

text
base:
  'web*':
    - mysql.client
    - mysql.python
  'db*':
    - mysql.server

This clear definition ensures that the user is properly informed of what each
state will do.

Another example comes from the :formula_url:vim-formula:

.. code-block:: bash

text
/srv/salt/vim/files/
/srv/salt/vim/absent.sls
/srv/salt/vim/init.sls
/srv/salt/vim/map.jinja
/srv/salt/vim/nerdtree.sls
/srv/salt/vim/pyflakes.sls
/srv/salt/vim/salt.sls

Once again viewing how this would look in a top file:

/srv/salt/top.sls:

.. code-block:: yaml

text
base:
  'web*':
    - vim
    - vim.nerdtree
    - vim.pyflakes
    - vim.salt
  'db*':
    - vim.absent

The usage of a clear top-level directory as well as properly named states
reduces the overall complexity and leads a user to both understand what will
be included at a glance and where it is located.

In addition :ref:Formulas <conventions-formula> should
be used as often as possible.

.. note::

text
Formulas repositories on the saltstack-formulas GitHub organization should
not be pointed to directly from systems that automatically fetch new
updates such as GitFS or similar tooling. Instead formulas repositories
should be forked on GitHub or cloned locally, where unintended, automatic
changes will not take place.

Structuring Pillar Files

:ref:Pillars are used to store
secure and insecure data pertaining to minions. When designing the structure
of the /srv/pillar directory, the pillars contained within
should once again be focused on clear and concise data which users can easily
review, modify, and understand.

The /srv/pillar/ directory is primarily controlled by top.sls. It
should be noted that the pillar top.sls is not used as a location to
declare variables and their values. The top.sls is used as a way to
include other pillar files and organize the way they are matched based on
environments or grains.

An example top.sls may be as simple as the following:

/srv/pillar/top.sls:

.. code-block:: yaml

text
base:
  '*':
    - packages

Any number of matchers can be added to the base environment. For example, here
is an expanded version of the Pillar top file stated above:

/srv/pillar/top.sls:

.. code-block:: yaml

text
base:
  '*':
    - packages
  'web*':
    - apache
    - vim

Or an even more complicated example, using a variety of matchers in numerous
environments:

/srv/pillar/top.sls:

.. code-block:: yaml

text
base:
  '*':
    - apache
dev:
  'os:Debian':
    - match: grain
    - vim
test:
  '* and not G@os: Debian':
    - match: compound
    - emacs

It is clear to see through these examples how the top file provides users with
power but when used incorrectly it can lead to confusing configurations. This
is why it is important to understand that the top file for pillar is not used
for variable definitions.

Each SLS file within the /srv/pillar/ directory should correspond to the
states which it matches.

This would mean that the apache pillar file should contain data relevant to
Apache. Structuring files in this way once again ensures modularity, and
creates a consistent understanding throughout our Salt environment. Users can
expect that pillar variables found in an Apache state will live inside of an
Apache pillar:

/srv/pillar/apache.sls:

.. code-block:: yaml

text
apache:
  lookup:
    name: httpd
    config:
      tmpl: /etc/httpd/httpd.conf

While this pillar file is simple, it shows how a pillar file explicitly
relates to the state it is associated with.

Variable Flexibility

Salt allows users to define variables in SLS files. When creating a state
variables should provide users with as much flexibility as possible. This
means that variables should be clearly defined and easy to manipulate, and
that sane defaults should exist in the event a variable is not properly
defined. Looking at several examples shows how these different items can
lead to extensive flexibility.

Although it is possible to set variables locally, this is generally not
preferred:

/srv/salt/apache/conf.sls:

.. code-block:: jinja

text
{% set name = 'httpd' %}
{% set tmpl = 'salt://apache/files/httpd.conf' %}

include:
  - apache

apache_conf:
  file.managed:
    - name: {{ name }}
    - source: {{ tmpl }}
    - template: jinja
    - user: root
    - watch_in:
      - service: apache

When generating this information it can be easily transitioned to the pillar
where data can be overwritten, modified, and applied to multiple states, or
locations within a single state:

/srv/pillar/apache.sls:

.. code-block:: yaml

text
apache:
  lookup:
    name: httpd
    config:
      tmpl: salt://apache/files/httpd.conf

/srv/salt/apache/conf.sls:

.. code-block:: jinja

text
{% from "apache/map.jinja" import apache with context %}

include:
  - apache

apache_conf:
  file.managed:
    - name: {{ salt['pillar.get']('apache:lookup:name') }}
    - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
    - template: jinja
    - user: root
    - watch_in:
      - service: apache

This flexibility provides users with a centralized location to modify
variables, which is extremely important as an environment grows.

Modularity Within States

Ensuring that states are modular is one of the key concepts to understand
within Salt. When creating a state a user must consider how many times the
state could be re-used, and what it relies on to operate. Below are several
examples which will iteratively explain how a user can go from a state which
is not very modular to one that is:

/srv/salt/apache/init.sls:

.. code-block:: yaml

text
httpd:
  pkg:
    - installed
  service.running:
    - enable: True

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

The example above is probably the worst-case scenario when writing a state.
There is a clear lack of focus by naming both the pkg/service, and managed
file directly as the state ID. This would lead to changing multiple requires
within this state, as well as others that may depend upon the state.

Imagine if a require was used for the httpd package in another state, and
then suddenly it's a custom package. Now changes need to be made in multiple
locations which increases the complexity and leads to a more error prone
configuration.

There is also the issue of having the configuration file located in the init,
as a user would be unable to simply install the service and use the default
conf file.

Our second revision begins to address the referencing by using - name, as
opposed to direct ID references:

/srv/salt/apache/init.sls:

.. code-block:: yaml

text
apache:
  pkg.installed:
    - name: httpd
  service.running:
    - name: httpd
    - enable: True

apache_conf:
  file.managed:
    - name: /etc/httpd/httpd.conf
    - source: salt://apache/files/httpd.conf
    - template: jinja
    - watch_in:
      - service: apache

The above init file is better than our original, yet it has several issues
which lead to a lack of modularity. The first of these problems is the usage
of static values for items such as the name of the service, the name of the
managed file, and the source of the managed file. When these items are hard
coded they become difficult to modify and the opportunity to make mistakes
arises. It also leads to multiple edits that need to occur when changing
these items (imagine if there were dozens of these occurrences throughout the
state!). There is also still the concern of the configuration file data living
in the same state as the service and package.

In the next example steps will be taken to begin addressing these issues.
Starting with the addition of a map.jinja file (as noted in the
:ref:Formula documentation <conventions-formula>), and
modification of static values:

/srv/salt/apache/map.jinja:

.. code-block:: jinja

text
{% set apache = salt['grains.filter_by']({
    'Debian': {
        'server': 'apache2',
        'service': 'apache2',
        'conf': '/etc/apache2/apache.conf',
    },
    'RedHat': {
        'server': 'httpd',
        'service': 'httpd',
        'conf': '/etc/httpd/httpd.conf',
    },
}, merge=salt['pillar.get']('apache:lookup')) %}

/srv/pillar/apache.sls:

.. code-block:: yaml

text
apache:
  lookup:
    config:
      tmpl: salt://apache/files/httpd.conf

/srv/salt/apache/init.sls:

.. code-block:: jinja

text
{% from "apache/map.jinja" import apache with context %}

apache:
  pkg.installed:
    - name: {{ apache.server }}
  service.running:
    - name: {{ apache.service }}
    - enable: True

apache_conf:
  file.managed:
    - name: {{ apache.conf }}
    - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
    - template: jinja
    - user: root
    - watch_in:
      - service: apache

The changes to this state now allow us to easily identify the location of the
variables, as well as ensuring they are flexible and easy to modify.
While this takes another step in the right direction, it is not yet complete.
Suppose the user did not want to use the provided conf file, or even their own
configuration file, but the default apache conf. With the current state setup
this is not possible. To attain this level of modularity this state will need
to be broken into two states.

/srv/salt/apache/map.jinja:

.. code-block:: jinja

text
{% set apache = salt['grains.filter_by']({
    'Debian': {
        'server': 'apache2',
        'service': 'apache2',
        'conf': '/etc/apache2/apache.conf',
    },
    'RedHat': {
        'server': 'httpd',
        'service': 'httpd',
        'conf': '/etc/httpd/httpd.conf',
    },
}, merge=salt['pillar.get']('apache:lookup')) %}

/srv/pillar/apache.sls:

.. code-block:: yaml

text
apache:
  lookup:
    config:
      tmpl: salt://apache/files/httpd.conf

/srv/salt/apache/init.sls:

.. code-block:: jinja

text
{% from "apache/map.jinja" import apache with context %}

apache:
  pkg.installed:
    - name: {{ apache.server }}
  service.running:
    - name: {{ apache.service }}
    - enable: True

/srv/salt/apache/conf.sls:

.. code-block:: jinja

text
{% from "apache/map.jinja" import apache with context %}

include:
  - apache

apache_conf:
  file.managed:
    - name: {{ apache.conf }}
    - source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}
    - template: jinja
    - user: root
    - watch_in:
      - service: apache

This new structure now allows users to choose whether they only wish to
install the default Apache, or if they wish, overwrite the default package,
service, configuration file location, or the configuration file itself. In
addition to this the data has been broken between multiple files allowing for
users to identify where they need to change the associated data.

Storing Secure Data

Secure data refers to any information that you would not wish to share with
anyone accessing a server. This could include data such as passwords,
keys, or other information.

As all data within a state is accessible by EVERY server that is connected
it is important to store secure data within pillar. This will ensure that only
those servers which require this secure data have access to it. In this
example a use can go from an insecure configuration to one which is only
accessible by the appropriate hosts:

/srv/salt/mysql/testerdb.sls:

.. code-block:: yaml

text
testdb:
  mysql_database.present:
    - name: testerdb

/srv/salt/mysql/user.sls:

.. code-block:: yaml

text
include:
  - mysql.testerdb

testdb_user:
  mysql_user.present:
    - name: frank
    - password: "test3rdb"
    - host: localhost
    - require:
      - sls: mysql.testerdb

Many users would review this state and see that the password is there in plain
text, which is quite problematic. It results in several issues which may not
be immediately visible.

The first of these issues is clear to most users -- the password being visible
in this state. This means that any minion will have a copy of this, and
therefore the password which is a major security concern as minions may not
be locked down as tightly as the master server.

The other issue that can be encountered is access by users on the master. If
everyone has access to the states (or their repository), then they are able to
review this password. Keeping your password data accessible by only a few
users is critical for both security and peace of mind.

There is also the issue of portability. When a state is configured this way
it results in multiple changes needing to be made. This was discussed in the
sections above but it is a critical idea to drive home. If states are not
portable it may result in more work later!

Fixing this issue is relatively simple, the content just needs to be moved to
the associated pillar:

/srv/pillar/mysql.sls:

.. code-block:: yaml

text
mysql:
  lookup:
    name: testerdb
    password: test3rdb
    user: frank
    host: localhost

/srv/salt/mysql/testerdb.sls:

.. code-block:: jinja

text
testdb:
  mysql_database.present:
    - name: {{ salt['pillar.get']('mysql:lookup:name') }}

/srv/salt/mysql/user.sls:

.. code-block:: jinja

text
include:
  - mysql.testerdb

testdb_user:
  mysql_user.present:
    - name: {{ salt['pillar.get']('mysql:lookup:user') }}
    - password: {{ salt['pillar.get']('mysql:lookup:password') }}
    - host: {{ salt['pillar.get']('mysql:lookup:host') }}
    - require:
      - sls: mysql.testerdb

Now that the database details have been moved to the associated pillar file,
only machines which are targeted via pillar will have access to these details.
Access to users who should not be able to review these details can also be
prevented while ensuring that they are still able to write states which take
advantage of this information.


Doc Topics Contributing Guide (`doc/topics/contributing-guide.rst`)

.. _contributing-import:

.. include:: ../../CONTRIBUTING.rst


Doc Topics Hardening (`doc/topics/hardening.rst`)

.. _hardening-salt:

============== Hardening Salt

This topic contains tips you can use to secure and harden your Salt
environment. How you best secure and harden your Salt environment depends
heavily on how you use Salt, where you use Salt, how your team is structured,
where you get data from, and what kinds of access (internal and external) you
require.

.. important::
The guidance here should be taken in combination with :ref:best-practices.

.. important::

text
Refer to the :ref:`saltstack_security_announcements` documentation in order to stay updated
and secure.

.. warning::

text
For historical reasons, Salt requires PyCrypto as a "lowest common
denominator". However, `PyCrypto is unmaintained`_ and best practice is to
manually upgrade to use a more maintained library such as `PyCryptodome`_. See
`Issue #52674`_ and `Issue #54115`_ for more info

.. _PyCrypto is unmaintained: https://github.com/dlitz/pycrypto/issues/301#issue-551975699
.. _PyCryptodome: https://pypi.org/project/pycryptodome/
.. _Issue #52674: https://github.com/saltstack/salt/issues/52674
.. _Issue #54115: https://github.com/saltstack/salt/issues/54115

General hardening tips

  • Restrict who can directly log into your Salt master system.
  • Use SSH keys secured with a passphrase to gain access to the Salt master system.
  • Track and secure SSH keys and any other login credentials you and your team
    need to gain access to the Salt master system.
  • Use a hardened bastion server or a VPN to restrict direct access to the Salt
    master from the internet.
  • Don't expose the Salt master any more than what is required.
  • Harden the system as you would with any high-priority target.
  • Keep the system patched and up-to-date.
  • Use tight firewall rules. Pay particular attention to TCP/4505 and TCP/4506
    on the salt master and avoid exposing these ports unnecessarily.

Salt hardening tips

.. include:: ../_incl/grains_passwords.rst

.. include:: ../_incl/jinja_security.rst

  • Subscribe to salt-users_ or salt-announce_ so you know when new Salt
    releases are available.
  • Keep your systems up-to-date with the latest patches.
  • Use Salt's Client :ref:ACL system <acl> to avoid having to give out root
    access in order to run Salt commands.
  • Use Salt's Client :ref:ACL system <acl> to restrict which users can run what commands.
  • Use :ref:external Pillar <all-salt.pillars> to pull data into Salt from
    external sources so that non-sysadmins (other teams, junior admins,
    developers, etc) can provide configuration data without needing access to the
    Salt master.
  • Make heavy use of SLS files that are version-controlled and go through
    a peer-review/code-review process before they're deployed and run in
    production. This is good advice even for "one-off" CLI commands because it
    helps mitigate typos and mistakes.
  • Use salt-api, SSL, and restrict authentication with the :ref:external auth <acl-eauth> system if you need to expose your Salt master to external
    services.
  • Make use of Salt's event system and :ref:reactor <reactor> to allow minions
    to signal the Salt master without requiring direct access.
  • Run the salt-master daemon as non-root.
  • Disable which modules are loaded onto minions with the
    :conf_minion:disable_modules setting. (for example, disable the cmd
    module if it makes sense in your environment.)
  • Look through the fully-commented sample :ref:master <configuration-examples-master> and :ref:minion <configuration-examples-minion> config files. There are many options for
    securing an installation.
  • Run :ref:masterless-mode <tutorial-standalone-minion> minions on
    particularly sensitive minions. There is also :ref:salt-ssh or the
    :mod:modules.sudo <salt.modules.sudo> if you need to further restrict
    a minion.
  • Monitor specific security related log messages. Salt salt-master logs
    attempts to access methods which are not exposed to network clients. These log
    messages are logged at the error log level and start with Requested method not exposed.

.. _rotating-salt-keys:

Rotating keys

There are several reasons to rotate keys. One example is exposure or a
compromised key. An easy way to rotate a key is to remove the existing keys and
let the salt-master or salt-minion process generate new keys on
restart.

Rotate a minion key

Run the following on the Salt minion:

.. code-block:: shell

salt-call saltutil.regen_keys
systemctl stop salt-minion

Run the following on the Salt master:

.. code-block:: shell

salt-key -d

Run the following on the Salt minion:

.. code-block:: shell

systemctl start salt-minion

Run the following on the Salt master:

.. code-block:: shell

salt-key -a

Rotate a master key

Run the following on the Salt master:

.. code-block:: shell

systemctl stop salt-master
rm /master.{pem,pub}
systemctl start salt-master

Run the following on the Salt minion:

.. code-block:: shell

systemctl stop salt-minion
rm /minion_master.pub
systemctl start salt-minion

.. _salt-users: https://groups.google.com/forum/#!forum/salt-users
.. _salt-announce: https://groups.google.com/forum/#!forum/salt-announce

Hardening of syndic setups

Syndics must be run as the same user as their syndic master process. The master
of master's will include publisher ACL information in jobs sent to downstream
masters via syndics. This means that any minions connected directly to a master
of masters will also receive ACL information in jobs being published. For the
most secure setup, only connect syndics directly to master of masters.


Doc Topics Index (`doc/topics/index.rst`)

.. _Apache 2.0 license: http://www.apache.org/licenses/LICENSE-2.0.html

==================== Introduction to Salt

.. rubric:: We’re not just talking about NaCl.

The 30 second summary

Salt is:

  • A configuration management system. Salt is capable of maintaining remote
    nodes in defined states. For example, it can ensure that specific packages are
    installed and that specific services are running.

  • A distributed remote execution system used to execute commands and
    query data on remote nodes.
    Salt can query and execute commands either on
    individual nodes or by using an arbitrary selection criteria.

It was developed in order to bring the best solutions found in the
world of remote execution together and make them better, faster, and more
malleable. Salt accomplishes this through its ability to handle large loads of
information, and not just dozens but hundreds and even thousands of individual
servers quickly through a simple and manageable interface.

Simplicity

Providing versatility between massive scale deployments and smaller systems may seem
daunting, but Salt is very simple to set up and maintain, regardless of the
size of the project. The architecture of Salt is designed to work with any
number of servers, from a handful of local network systems to international
deployments across different data centers. The topology is a simple
server/client model with the needed functionality built into a single set of
daemons. While the default configuration will work with little to no
modification, Salt can be fine tuned to meet specific needs.

Parallel execution

The core functions of Salt:

  • enable commands to remote systems to be called in parallel rather than serially
  • use a secure and encrypted protocol
  • use the smallest and fastest network payloads possible
  • provide a simple programming interface

Salt also introduces more granular controls to the realm of remote
execution, allowing systems to be targeted not just by hostname, but
also by system properties.

Builds on proven technology

Salt takes advantage of a number of technologies and techniques. The
networking layer is built with the excellent ZeroMQ_ networking
library, so the Salt daemon includes a viable and transparent AMQ
broker. Salt uses public keys for authentication with the master
daemon, then uses faster AES_ encryption for payload communication;
authentication and encryption are integral to Salt. Salt takes
advantage of communication via msgpack_, enabling fast and light
network traffic.

.. _ZeroMQ: https://zeromq.org/
.. _msgpack: https://msgpack.org/
.. _AES: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

Python client interface

In order to allow for simple expansion, Salt execution routines can be written
as plain Python modules. The data collected from Salt executions can be sent
back to the master server, or to any arbitrary program. Salt can be called from
a simple Python API, or from the command line, so that Salt can be used to
execute one-off commands as well as operate as an integral part of a larger
application.

Fast, flexible, scalable

The result is a system that can execute commands at high speed on
target server groups ranging from one to very many servers. Salt is
very fast, easy to set up, amazingly malleable and provides a single
remote execution architecture that can manage the diverse
requirements of any number of servers. The Salt infrastructure
brings together the best of the remote execution world, amplifies its
capabilities and expands its range, resulting in a system that is as
versatile as it is practical, suitable for any network.

Open

Salt is developed under the Apache 2.0 license_, and can be used for
open and proprietary projects. Please submit your expansions back to
the Salt project so that we can all benefit together as Salt grows.
Please feel free to sprinkle Salt around your systems and let the
deliciousness come forth.


Doc Topics Maintenance Policy (`doc/topics/maintenance-policy.rst`)

.. _maintenance-policy-import:

.. include:: ../../POLICY.rst


Doc Topics Salt System Architecture (`doc/topics/salt_system_architecture.rst`)

.. _salt-system-architecture:

======================== Salt system architecture

Overview

This page provides a high-level overview of the Salt system architecture and its
different components.

What is Salt?

Salt is a Python-based open-source remote execution framework used for:

  • Configuration management
  • Automation
  • Provisioning
  • Orchestration

The Salt system architecture

The following diagram shows the primary components of the basic Salt
architecture:

.. image:: /_static/salt-architecture.png
:width: 80%

The following sections describe some of the core components of the Salt
architecture.

Salt Masters and Salt Minions

Salt uses the master-client model in which a master issues commands to a client
and the client executes the command. In the Salt ecosystem, the Salt Master is a
server that is running the salt-master service. It issues commands to one or
more Salt Minions, which are servers that are running the salt-minion
service and that are registered with that particular Salt Master.

Another way to describe Salt is as a publisher-subscriber model. The master
publishes jobs that need to be executed and Salt Minions subscribe to those
jobs. When a specific job applies to that minion, it will execute the job.

When a minion finishes executing a job, it sends job return data back to the
master. Salt has two ports used by default for the minions to communicate with
their master(s). These ports work in concert to receive and deliver data to the
Message Bus. Salt’s message bus is ZeroMQ, which creates an asynchronous network
topology to provide the fastest communication possible.

Targets and grains

The master indicates which minions should execute the job by defining a
target. A target is the group of minions, across one or many masters, that a
job's Salt command applies to.

.. Note::
A master can also be managed like a minion and can be a target if it is
running the salt-minion service.

The following is an example of one of the many kinds of commands that a master
might issue to a minion. This command indicates that all minions should install
the Vim application:

.. code-block:: bash

text
salt -v '*' pkg.install vim

In this case the glob '*' is the target, which indicates that all minions
should execute this command. Many other targeting options are available,
including targeting a specific minion by its ID or targeting minions by their
shared traits or characteristics (called grains in Salt).

Salt comes with an interface to derive information about the underlying system.
This is called the grains interface, because it presents Salt with grains of
information. Grains are collected for the operating system, domain name,
IP address, kernel, OS type, memory, and many other system properties. You can
also create your own custom grain data.

Grain data is relatively static. However, grain data is refreshed when system
information changes (such as network settings) or when a new value is assigned
to a custom grain.

Open event system (event bus)

The event system is used for inter-process communication between the Salt Master
and Salt Minions. In the event system:

  • Events are seen by both the master and minions.
  • Events can be monitored and evaluated by both.

The event bus lays the groundwork for orchestration and real-time monitoring.

All minions see jobs and results by subscribing to events published on the event
system. Salt uses a pluggable event system with two layers:

  • ZeroMQ (0MQ) - The current default socket-level library providing a
    flexible transport layer.
  • Tornado - Full TCP-based transport layer event system.

One of the greatest strengths of Salt is the speed of execution. The event
system’s communication bus is more efficient than running a higher-level web
service (http). The remote execution system is the component that all components
are built upon, allowing for decentralized remote execution to spread load
across resources.

Salt states

In addition to remote execution, Salt provides another method for configuring
minions by declaring which state a minion should be in, otherwise referred to
as Salt states. Salt states make configuration management possible. You can
use Salt states to deploy and manage infrastructure with simple YAML files.
Using states, you can automate recursive and predictable tasks by queueing jobs
for Salt to implement without needing user input. You can also add more complex
conditional logic to state files with Jinja.

To illustrate the subtle differences between remote execution and configuration
management, take the command referenced in the previous section about
Targets and grains_ in which Salt installed the application Vim on all
minions:

.. list-table::
:widths: 25 25 50
:header-rows: 1

    • Methodology
    • Implementation
    • Result
    • Remote execution
      • Run salt -v '*' pkg.install vim from the terminal
      • Remotely installs Vim on the targeted minions
    • Configuration management
      • Write a YAML state file that checks whether Vim is installed
      • This state file is then applied to the targeted minions
      • Ensures that Vim is always installed on the targeted minions
      • Salt analyzes the state file and determines what actions need to be
        taken to ensure the minion complies with the state declarations
      • If Vim is not installed, it automates the processes to install Vim on
        the targeted minions

The state file that verifies Vim is installed might look like the following
example:

.. code-block:: yaml

text
# File:/srv/salt/vim_install.sls

install_vim_now:
  pkg.installed:
    - pkgs:
      - vim

To apply this state to a minion, you would use the state.apply module, such
as in the following example:

.. code-block:: bash

text
salt '*' state.apply vim_install

This command applies the vim_install state to all minions.

Formulas are collections of states that work in harmony to configure a minion
or application. For example, one state might trigger another state.

The Top file

It is not practical to manually run each state individually targeting specific
minions each time. Some environments have hundreds of state files targeting
thousands of minions.

Salt offers two features to help with this scaling problem:

  • The top.sls file - Maps Salt states to their applicable minions.
  • Highstate execution - Runs all Salt states outlined in top.sls in a
    single execution.

The top file maps which states should be applied to different minions in certain
environments. The following is an example of a simple top file:

.. code-block:: yaml

text
# File: /srv/salt/top.sls

base:
  '*':
    - all_server_setup

  '01webserver':
    - web_server_setup

In this example, base refers to the Salt environment, which is the default.
You can specify more than one environment as needed, such as prod, dev, QA, etc.

Groups of minions are specified under the environment, and states are listed for
each set of minions. This top file indicates that a state called
all_server_setup should be applied to all minions '*' and the state
called web_server_setup should be applied to the 01webserver minion.

To run the Salt command, you would use the state.highstate function:

.. code-block:: bash

text
salt \* state.highstate

This command applies the top file to the targeted minions.

Salt pillar

Salt’s pillar feature takes data defined on the Salt Master and distributes it
to minions as needed. Pillar is primarily used to store secrets or other highly
sensitive data, such as account credentials, cryptographic keys, or passwords.
Pillar is also useful for storing non-secret data that you don't want to place
directly in your state files, such as configuration data.

Salt pillar brings data into the cluster from the opposite direction as grains.
While grains are data generated from the minion, the pillar is data generated
from the master.

Pillars are organized similarly to states in a Pillar state tree, where
top.sls acts to coordinate pillar data to environments and minions privy to
the data. Information transferred using pillar has a dictionary generated for
the targeted minion and encrypted with that minion’s key for secure data
transfer. Pillar data is encrypted on a per-minion basis, which makes it useful
for storing sensitive data specific to a particular minion.

Beacons and reactors

The beacon system is a monitoring tool that can listen for a variety of system
processes on Salt Minions. Beacons can trigger reactors which can then help
implement a change or troubleshoot an issue. For example, if a service’s
response times out, the reactor system can restart the service.

Beacons are used for a variety of purposes, including:

  • Automated reporting
  • Error log delivery
  • Microservice monitoring
  • User shell activity
  • Resource monitoring

When coupled with reactors, beacons can create automated pre-written responses
to infrastructure and application issues. Reactors expand Salt with automated
responses using pre-written remediation states.

Reactors can be applied in a variety of scenarios:

  • Infrastructure scaling
  • Notifying administrators
  • Restarting failed applications
  • Automatic rollback

When both beacons and reactors are used together , you can create unique states
customized to your specific needs.

Salt runners and orchestration

Salt runners are convenience applications executed with the salt-run
command. Salt runners work similarly to Salt execution modules. However, they
execute on the Salt Master instead of the Salt Minions. A Salt runner can be a
simple client call or a complex application.

Salt provides the ability to orchestrate system administrative tasks throughout
the enterprise. Orchestration makes it possible to coordinate the activities of
multiple machines from a central place. It has the added advantage of being able
to control the sequence of when certain configuration events occur.
Orchestration states execute on the master using the state runner module.


Doc Topics Using Salt (`doc/topics/using_salt.rst`)

========== Using Salt

This section describes the fundamental components and concepts that you need to understand to use Salt.

.. toctree::
:maxdepth: 1

text
grains/index
pillar/index
targeting/index
mine/index
../ref/runners/index
engines/index
yaml/index
jinja/index
tutorials/index
troubleshooting/index
../faq
best_practices

Doc Ref Cli Index (`doc/ref/cli/index.rst`)

====================== Command Line Reference

salt-api

.. toctree::

text
salt-api

salt-call

.. toctree::

text
salt-call

salt

.. toctree::

text
salt

salt-cloud

.. toctree::

text
salt-cloud

salt-cp

.. toctree::

text
salt-cp

salt-extend

.. toctree::

text
salt-extend

salt-key

.. toctree::

text
salt-key

salt-master

.. toctree::

text
salt-master

salt-minion

.. toctree::

text
salt-minion

salt-proxy

.. toctree::

text
salt-proxy

salt-run

.. toctree::

text
salt-run

salt-ssh

.. toctree::

text
salt-ssh

salt-syndic

.. toctree::

text
salt-syndic

spm

.. toctree::

text
spm

Doc Ref Cli Salt Api (`doc/ref/cli/salt-api.rst`)

============ ``salt-api``

Start interfaces used to remotely connect to the salt master

Synopsis

.. code-block:: bash

text
salt-api

Description

The Salt API system manages network api connectors for the Salt Master

Options

.. program:: salt-api

.. include:: _includes/common-options.rst

.. option:: -d, --daemon

text
Run the salt-api as a daemon

.. option:: --pid-file=PIDFILE

text
Specify the location of the pidfile. Default: /var/run/salt-api.pid

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/api
.. |loglevel| replace:: warning

See also

:manpage:salt-api(7)
:manpage:salt(7)
:manpage:salt-master(1)


Doc Ref Cli Salt Call (`doc/ref/cli/salt-call.rst`)

============= ``salt-call``

Synopsis

.. code-block:: bash

text
salt-call [options]

Description

The salt-call command is used to run module functions locally on a minion
instead of executing them from the master. Salt-call is used to run a
:ref:Standalone Minion <tutorial-standalone-minion>, and was originally
created for :ref:troubleshooting .

The Salt Master is contacted to retrieve state files and other resources
during execution unless the --local option is specified.

.. note::

text
``salt-call`` commands execute from the current user's shell
context, while ``salt`` commands execute from the system's default context.

Options

.. program:: salt-call

.. include:: _includes/common-options.rst

.. option:: --hard-crash

text
Raise any original exception rather than exiting gracefully Default: False

.. option:: -g, --grains

text
Return the information generated by the Salt grains

.. option:: -m MODULE_DIRS, --module-dirs=MODULE_DIRS

text
Specify an additional directory to pull modules from.  Multiple directories
can be provided by passing -m /--module-dirs multiple times.

.. option:: -d, --doc, --documentation

text
Return the documentation for the specified module or for all modules if
none are specified

.. option:: --master=MASTER

text
Specify the master to use. The minion must be authenticated with the
master. If this option is omitted, the master options from the minion
config will be used. If multi masters are set up the first listed master
that responds will be used.

.. option:: --return RETURNER

text
Set salt-call to pass the return data to one or many returner interfaces.
To use many returner interfaces specify a comma delimited list of
returners.

.. option:: --local

text
Run salt-call locally, as if there was no master running.

.. option:: --file-root=FILE_ROOT

text
Set this directory as the base file root. Can be specified more than once
to include multiple base file roots.

.. option:: --pillar-root=PILLAR_ROOT

text
Set this directory as the base pillar root. Can be specified more than
once to include multiple base pillar roots.

.. option:: --states-dir=STATES_DIR

text
Set this directory to search for additional states. Can be specified more
than once to include multiple states directories.

.. option:: --retcode-passthrough

text
Exit with the salt call retcode and not the salt binary retcode

.. option:: --no-return-event

text
Do not send the return event back to master.

.. option:: --metadata

text
Print out the execution metadata as well as the return. This will print out
the outputter data, the return code, etc.

.. option:: --id=ID

text
Specify the minion id to use. If this option is omitted, the id option from
the minion config will be used.

.. option:: --skip-grains

text
Do not load grains.

.. option:: --refresh-grains-cache

text
Force a refresh of the grains cache

.. option:: -r, --resources

text
.. versionadded:: 3008.0

Dispatch the call to managed resources in addition to the managing
minion. Without ``-r``, ``salt-call`` runs the function on the
managing minion only and returns a single bare value, preserving
legacy script behaviour. With ``-r``, the function runs against
every resource matched by ``--tgt`` and the result is a dict keyed
by resource id (or by managing-minion id, for the host itself).

See :ref:`resources-operations` for usage and :ref:`resources` for
background.

.. option:: --tgt=TGT

text
.. versionadded:: 3008.0

Targeting expression. Only honoured when ``-r``/``--resources`` is
also passed. Default ``*`` — matches the managing minion and all
managed resources. Supports all targeting forms documented in
:ref:`resources-targeting`, controlled by ``--tgt-type``.

.. option:: --tgt-type=TGT_TYPE

text
.. versionadded:: 3008.0

Targeting expression type. Only honoured when ``-r``/``--resources``
is also passed. Mirrors the master CLI's ``-t``/``--target-type``
options. Common values: ``glob`` (default), ``compound``, ``grain``,
``grain_pcre``, ``list``, ``pillar``, ``range``, ``pcre``.

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/minion
.. |loglevel| replace:: warning

.. include:: _includes/output-options.rst

See also

:manpage:salt(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Cloud (`doc/ref/cli/salt-cloud.rst`)

============== ``salt-cloud``

Provision virtual machines in the cloud with Salt

Synopsis

.. code-block:: bash

text
salt-cloud -m /etc/salt/cloud.map

salt-cloud -m /etc/salt/cloud.map NAME

salt-cloud -m /etc/salt/cloud.map NAME1 NAME2

salt-cloud -p PROFILE NAME

salt-cloud -p PROFILE NAME1 NAME2 NAME3 NAME4 NAME5 NAME6

Description

Salt Cloud is the system used to provision virtual machines on various public
clouds via a cleanly controlled profile and mapping system.

Options

.. program:: salt-cloud

.. include:: _includes/common-options.rst

Execution Options

.. option:: -L LOCATION, --location=LOCATION

text
Specify which region to connect to.

.. option:: -a ACTION, --action=ACTION

text
Perform an action that may be specific to this cloud provider. This
argument requires one or more instance names to be specified.

.. option:: -f , --function=

text
Perform an function that may be specific to this cloud provider, that does
not apply to an instance. This argument requires a provider to be specified
(i.e.: nova).

.. option:: -p PROFILE, --profile=PROFILE

text
Select a single profile to build the named cloud VMs from. The profile must
be defined in the specified profiles file.

.. option:: -m MAP, --map=MAP

text
Specify a map file to use. If used without any other options, this option
will ensure that all of the mapped VMs are created. If the named VM already
exists then it will be skipped.

.. option:: -H, --hard

text
When specifying a map file, the default behavior is to ensure that all of
the VMs specified in the map file are created. If the --hard option is
set, then any VMs that exist on configured cloud providers that are
not specified in the map file will be destroyed. Be advised that this can
be a destructive operation and should be used with care.

.. option:: -d, --destroy

text
Pass in the name(s) of VMs to destroy, salt-cloud will search the
configured cloud providers for the specified names and destroy the
VMs. Be advised that this is a destructive operation and should be used
with care. Can be used in conjunction with the -m option to specify a map
of VMs to be deleted.

.. option:: -P, --parallel

text
Normally when building many cloud VMs they are executed serially. The -P
option will run each cloud vm build in a separate process allowing for
large groups of VMs to be build at once.

Be advised that some cloud provider's systems don't seem to be well suited
for this influx of vm creation. When creating large groups of VMs watch the
cloud provider carefully.

.. option:: -u, --update-bootstrap

text
Update salt-bootstrap to the latest stable bootstrap release.

.. option:: -y, --assume-yes

text
Default yes in answer to all confirmation questions.

.. option:: -k, --keep-tmp

text
Do not remove files from /tmp/ after deploy.sh finishes.

.. option:: --show-deploy-args

text
Include the options used to deploy the minion in the data returned.

.. option:: --script-args=SCRIPT_ARGS

text
Script arguments to be fed to the bootstrap script when deploying the VM.

Query Options

.. option:: -Q, --query

text
Execute a query and return some information about the nodes running on
configured cloud providers

.. option:: -F, --full-query

text
Execute a query and print out all available information about all cloud VMs.
Can be used in conjunction with -m to display only information about the
specified map.

.. option:: -S, --select-query

text
Execute a query and print out selected information about all cloud VMs.
Can be used in conjunction with -m to display only information about the
specified map.

.. option:: --list-providers

text
Display a list of configured providers.

.. option:: --list-profiles

text
.. versionadded:: 2014.7.0

Display a list of configured profiles. Pass in a cloud provider to view
the provider's associated profiles, such as ``digitalocean``, or pass in
``all`` to list all the configured profiles.

Cloud Providers Listings

.. option:: --list-locations=LIST_LOCATIONS

text
Display a list of locations available in configured cloud providers. Pass
the cloud provider that available locations are desired on, such as "linode",
or pass "all" to list locations for all configured cloud providers

.. option:: --list-images=LIST_IMAGES

text
Display a list of images available in configured cloud providers. Pass the
cloud provider that available images are desired on, such as "linode", or pass
"all" to list images for all configured cloud providers

.. option:: --list-sizes=LIST_SIZES

text
Display a list of sizes available in configured cloud providers. Pass the
cloud provider that available sizes are desired on, such as "AWS", or pass
"all" to list sizes for all configured cloud providers

Cloud Credentials

.. option:: --set-password=

text
Configure password for a cloud provider and save it to the keyring.
PROVIDER can be specified with or without a driver, for example:
"--set-password bob rackspace" or more specific "--set-password bob
rackspace:openstack" DEPRECATED!

.. include:: _includes/output-options.rst

Examples

To create 4 VMs named web1, web2, db1, and db2 from specified profiles:

.. code-block:: bash

text
salt-cloud -p fedora_rackspace web1 web2 db1 db2

To read in a map file and create all VMs specified therein:

.. code-block:: bash

text
salt-cloud -m /path/to/cloud.map

To read in a map file and create all VMs specified therein in parallel:

.. code-block:: bash

text
salt-cloud -m /path/to/cloud.map -P

To delete any VMs specified in the map file:

.. code-block:: bash

text
salt-cloud -m /path/to/cloud.map -d

To delete any VMs NOT specified in the map file:

.. code-block:: bash

text
salt-cloud -m /path/to/cloud.map -H

To display the status of all VMs specified in the map file:

.. code-block:: bash

text
salt-cloud -m /path/to/cloud.map -Q

See also

:manpage:salt-cloud(7)
:manpage:salt(7)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Cp (`doc/ref/cli/salt-cp.rst`)

=========== ``salt-cp``

Copy a file or files to one or more minions

Synopsis

.. code-block:: bash

text
salt-cp '*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST

salt-cp -E '.*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST

salt-cp -G 'os:Arch.*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST

Description

salt-cp copies files from the master to all of the Salt minions matched by the
specified target expression.

.. note::
salt-cp uses Salt's publishing mechanism. This means the privacy of the
contents of the file on the wire is completely dependent upon the transport
in use. In addition, if the master or minion is running with debug logging,
the contents of the file will be logged to disk.

text
In addition, this tool is less efficient than the Salt fileserver when
copying larger files. It is recommended to instead use
:py:func:`cp.get_file <salt.modules.cp.get_file>` to copy larger files to
minions. However, this requires the file to be located within one of the
fileserver directories.

.. versionchanged:: 2016.3.7,2016.11.6,2017.7.0
Compression support added, disable with -n. Also, if the destination
path ends in a path separator (i.e. /, or \ on Windows, the
desitination will be assumed to be a directory. Finally, recursion is now
supported, allowing for entire directories to be copied.

.. versionchanged:: 2016.11.7,2017.7.2
Reverted back to the old copy mode to preserve backward compatibility. The
new functionality added in 2016.6.6 and 2017.7.0 is now available using the
-C or --chunked CLI arguments. Note that compression, recursive
copying, and support for copying large files is only available in chunked
mode.

Options

.. program:: salt-cp

.. include:: _includes/common-options.rst

.. include:: _includes/timeout-option.rst
.. |timeout| replace:: 5

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/master
.. |loglevel| replace:: warning

.. include:: _includes/target-selection.rst

.. option:: -C, --chunked

text
Use new chunked mode to copy files. This mode supports large files, recursive
directories copying and compression.

.. versionadded:: 2016.11.7,2017.7.2

.. option:: -n, --no-compression

text
Disable gzip compression in chunked mode.

.. versionadded:: 2016.3.7,2016.11.6,2017.7.0

See also

:manpage:salt(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Extend (`doc/ref/cli/salt-extend.rst`)

.. _salt-extend:

=============== ``salt-extend``

A utilty to generate extensions to the Salt source-code. This is used for :

  • Adding new execution modules, state modules
  • Adding unit tests to existing modules
  • Adding integration tests to existing modules

Synopsis

.. code-block:: bash

text
salt-extend --help

Description

salt-extend is a templating tool for extending SaltStack. If you're looking to add a module to
SaltStack, then the salt-extend utility can guide you through the process.

You can use Salt Extend to quickly create templated modules for adding new behaviours to some of the module subsystems within Salt.

Salt Extend takes a template directory and merges it into a SaltStack source code directory.

See also: :ref:Salt Extend <development-salt-extend>.

Options

.. program:: salt-extend

.. option:: --extension, -e

text
The extension type you want to develop, e.g. module, module_unit, state

.. option:: --salt-directory, -o

text
The path to the salt installation, defaults to .

.. option:: --name, -n

text
The module name for the new module

.. option:: --description, -d

text
A description of the new extension

.. option:: --no-merge

text
Don't merge the new module into the Salt source directory specified by `--salt-directory`, save
to a temporary directory and print the directory path

.. option:: --debug

text
Print debug messages to stdout

See also

:manpage:salt-api(1)
:manpage:salt-call(1)
:manpage:salt-cloud(1)
:manpage:salt-cp(1)
:manpage:salt-key(1)
:manpage:salt-main(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)
:manpage:salt-run(1)
:manpage:salt-ssh(1)
:manpage:salt-syndic(1)


Doc Ref Cli Salt Key (`doc/ref/cli/salt-key.rst`)

.. _salt-key:

============ ``salt-key``

Synopsis

.. code-block:: bash

text
salt-key [ options ]

Description

Salt-key executes simple management of Salt server public keys used for
authentication.

On initial connection, a Salt minion sends its public key to the Salt
master. This key must be accepted using the salt-key command on the
Salt master.

Salt minion keys can be in one of the following states:

  • unaccepted: key is waiting to be accepted.
  • accepted: key was accepted and the minion can communicate with the Salt
    master.
  • rejected: key was rejected using the salt-key command. In
    this state the minion does not receive any communication from the Salt
    master.
  • denied: key was rejected automatically by the Salt master.
    This occurs when a minion has a duplicate ID, or when a minion was rebuilt or
    had new keys generated and the previous key was not deleted from the Salt
    master. In this state the minion does not receive any communication from the
    Salt master.

To change the state of a minion key, use -d to delete the key and then
accept or reject the key.

Options

.. program:: salt-key

.. include:: _includes/common-options.rst

.. option:: -u USER, --user=USER

text
Specify user to run salt-key

.. option:: --hard-crash

text
Raise any original exception rather than exiting gracefully. Default is
False.

.. option:: -q, --quiet

Suppress output

.. option:: -y, --yes

Answer 'Yes' to all questions presented, defaults to False

.. option:: --rotate-aes-key=ROTATE_AES_KEY

text
Setting this to False prevents the master from refreshing the key session
when keys are deleted or rejected, this lowers the security of the key
deletion/rejection operation. Default is True.

.. include:: _includes/logging-options.rst
:end-before: start-console-output
.. include:: _includes/logging-options.rst
:start-after: stop-console-output
.. |logfile| replace:: /var/log/salt/minion
.. |loglevel| replace:: warning

.. include:: _includes/output-options.rst

Actions

.. option:: -l ARG, --list=ARG

text
List the public keys. The args ``pre``, ``un``, and ``unaccepted`` will
list unaccepted/unsigned keys. ``acc`` or ``accepted`` will list
accepted/signed keys. ``rej`` or ``rejected`` will list rejected keys.
Finally, ``all`` will list all keys.

.. option:: -L, --list-all

text
List all public keys. (Deprecated: use ``--list all``)

.. option:: -a ACCEPT, --accept=ACCEPT

text
Accept the specified public key (use --include-all to match rejected keys
in addition to pending keys). Globs are supported.

.. option:: -A, --accept-all

text
Accepts all pending keys.

.. option:: -r REJECT, --reject=REJECT

text
Reject the specified public key (use --include-all to match accepted keys
in addition to pending keys). Globs are supported.

.. option:: -R, --reject-all

text
Rejects all pending keys.

.. option:: --include-all

text
Include non-pending keys when accepting/rejecting.

.. option:: -p PRINT, --print=PRINT

text
Print the specified public key.

.. option:: -P, --print-all

text
Print all public keys

.. option:: -d DELETE, --delete=DELETE

text
Delete the specified key. Globs are supported.

.. option:: -D, --delete-all

text
Delete all keys.

.. option:: -f FINGER, --finger=FINGER

text
Print the specified key's fingerprint.

.. option:: -F, --finger-all

text
Print all keys' fingerprints.

Key Generation Options

.. option:: --gen-keys=GEN_KEYS

Set a name to generate a keypair for use with salt

.. option:: --gen-keys-dir=GEN_KEYS_DIR

Set the directory to save the generated keypair. Only works
with 'gen_keys_dir' option; default is the current directory.

.. option:: --keysize=KEYSIZE

Set the keysize for the generated key, only works with
the '--gen-keys' option, the key size must be 2048 or
higher, otherwise it will be rounded up to 2048. The
default is 2048.

.. option:: --gen-signature

text
Create a signature file of the master's public-key named
master_pubkey_signature. The signature can be sent to a minion in the
master's auth-reply and enables the minion to verify the master's public-key
cryptographically. This requires a new signing-key-pair which can be
auto-created with the --auto-create parameter.

.. option:: --priv=PRIV

text
The private-key file to create a signature with

.. option:: --signature-path=SIGNATURE_PATH

text
The path where the signature file should be written

.. option:: --pub=PUB

text
The public-key file to create a signature for

.. option:: --auto-create

text
Auto-create a signing key-pair if it does not yet exist

See also

:manpage:salt(7)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Master (`doc/ref/cli/salt-master.rst`)

=============== ``salt-master``

The Salt master daemon, used to control the Salt minions

Synopsis

.. code-block:: bash

text
salt-master [ options ]

Description

The master daemon controls the Salt minions

Options

.. program:: salt-master

.. include:: _includes/common-options.rst

.. include:: _includes/daemon-options.rst
.. |salt-daemon| replace:: salt-master

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/master
.. |loglevel| replace:: warning

See also

:manpage:salt(1)
:manpage:salt(7)
:manpage:salt-minion(1)


Doc Ref Cli Salt Minion (`doc/ref/cli/salt-minion.rst`)

=============== ``salt-minion``

The Salt minion daemon, receives commands from a remote Salt master.

Synopsis

.. code-block:: bash

text
salt-minion [ options ]

Description

The Salt minion receives commands from the central Salt master and replies with
the results of said commands.

Options

.. program:: salt-minion

.. include:: _includes/common-options.rst

.. include:: _includes/daemon-options.rst
.. |salt-daemon| replace:: salt-minion

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/minion
.. |loglevel| replace:: warning

See also

:manpage:salt(1)
:manpage:salt(7)
:manpage:salt-master(1)


Doc Ref Cli Salt Proxy (`doc/ref/cli/salt-proxy.rst`)

.. _salt-proxy-cli:

============== ``salt-proxy``

Receives commands from a Salt master and proxies these commands to
devices that are unable to run a full minion.

Synopsis

.. code-block:: bash

text
salt-proxy [ options ]

Description

The Salt proxy minion receives commands from a Salt master, transmits
appropriate commands to devices that are unable to run a minion, and replies
with the results of said commands.

Options

.. program:: salt-proxy

.. option:: --proxyid

text
The minion id that this proxy will assume.  This is required.

.. option:: --version

text
Print the version of Salt that is running.

.. option:: --versions-report

text
Show program's dependencies and version number, and then exit

.. option:: -h, --help

Show the help message and exit

.. option:: -c CONFIG_DIR, --config-dir=CONFIG_dir

The location of the Salt configuration directory. This directory
contains the configuration files for Salt master and minions.
The default location on most systems is /etc/salt.

.. option:: -u USER, --user=USER

Specify user to run salt-proxy

.. option:: -d, --daemon

Run salt-proxy as a daemon

.. option:: --pid-file PIDFILE

Specify the location of the pidfile. Default: /var/run/salt-proxy-.pid

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/minion
.. |loglevel| replace:: warning

See also

:manpage:salt(1)
:manpage:salt(7)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Run (`doc/ref/cli/salt-run.rst`)

.. _salt-run:

============ ``salt-run``

Execute a Salt runner

Synopsis

.. code-block:: bash

text
salt-run RUNNER

Description

salt-run is the frontend command for executing Salt Runners.
Salt runners are simple modules used to execute convenience functions on the
master

Options

.. program:: salt-run

.. include:: _includes/common-options.rst

.. include:: _includes/timeout-option.rst
.. |timeout| replace:: 1

.. option:: --hard-crash

text
Raise any original exception rather than exiting gracefully. Default is
False.

.. option:: -d, --doc, --documentation

text
Display documentation for runners, pass a module or a runner to see
documentation on only that module/runner.

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/master
.. |loglevel| replace:: warning

See also

:manpage:salt(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Ssh (`doc/ref/cli/salt-ssh.rst`)

.. _cli-salt-ssh:

============ ``salt-ssh``

Synopsis

.. code-block:: bash

text
salt-ssh '*' [ options ] sys.doc

salt-ssh -E '.*' [ options ] sys.doc cmd

Description

Salt SSH allows for salt routines to be executed using only SSH for transport

Options

.. program:: salt-ssh

.. include:: _includes/common-options.rst

.. option:: --hard-crash

Raise any original exception rather than exiting gracefully. Default: False.

.. option:: -r, --raw, --raw-shell

text
Execute a raw shell command.

.. option:: --roster

text
Define which roster system to use, this defines if a database backend,
scanner, or custom roster system is used. Default is the flat file roster.

.. option:: --roster-file

text
Define an alternative location for the default roster file location. The
default roster file is called ``roster`` and is found in the same directory
as the master config file.

.. versionadded:: 2014.1.0

.. option:: --refresh, --refresh-cache

text
Force a refresh of the master side data cache of the target's data. This
is needed if a target's grains have been changed and the auto refresh
timeframe has not been reached.

.. option:: --max-procs

text
Set the number of concurrent minions to communicate with. This value
defines how many processes are opened up at a time to manage connections,
the more running process the faster communication should be, default
is 25.

.. option:: --extra-filerefs=EXTRA_FILEREFS

Pass in extra files to include in the state tarball.

.. option:: --min-extra-modules=MIN_EXTRA_MODS

text
One or comma-separated list of extra Python modulesto be included
into Minimal Salt.

.. option:: --thin-extra-modules=THIN_EXTRA_MODS

One or comma-separated list of extra Python modulesto be included
into Thin Salt.

.. option:: -v, --verbose

Turn on command verbosity, display jid.

.. option:: -s, --static

Return the data from minions as a group after they all return.

.. option:: -w, --wipe

Remove the deployment of the salt files when done executing.

.. option:: -W, --rand-thin-dir

Select a random temp dir to deploy on the remote system. The dir
will be cleaned after the execution.

.. option:: -t, --regen-thin, --thin

Trigger a thin tarball regeneration. This is needed if custom
grains/modules/states have been added or updated.

.. option:: --python2-bin=PYTHON2_BIN

Path to a python2 binary which has salt installed.

.. option:: --python3-bin=PYTHON3_BIN

Path to a python3 binary which has salt installed.

.. option:: --jid=JID

Pass a JID to be used instead of generating one.

.. option:: --pre-flight

Run the ssh_pre_flight script defined in the roster.
By default this script will only run if the thin dir
does not exist on the target minion. This option will
force the script to run regardless of the thin dir
existing or not.

Authentication Options

.. option:: --priv=SSH_PRIV

text
Specify the SSH private key file to be used for authentication.

.. option:: --priv-passwd=SSH_PRIV_PASSWD

text
Specify the SSH private key file's passphrase if need be.

.. option:: -i, --ignore-host-keys

text
By default ssh host keys are honored and connections  will ask for
approval. Use this option to disable StrictHostKeyChecking.

.. option:: --no-host-keys

text
Fully ignores ssh host keys which by default are honored and connections
would ask for approval. Useful if the host key of a remote server has
changed and would still error with --ignore-host-keys.

.. option:: --user=SSH_USER

text
Set the default user to attempt to use when authenticating.

.. option:: --passwd

text
Set the default password to attempt to use when authenticating.

.. option:: --askpass

text
Interactively ask for the SSH password with no echo - avoids password
in process args and stored in history.

.. option:: --key-deploy

Set this flag to attempt to deploy the authorized ssh key with all
minions. This combined with --passwd can make initial deployment of keys
very fast and easy.

.. option:: --identities-only

Use the only authentication identity files configured in the ssh_config
files. See IdentitiesOnly flag in man ssh_config.

.. option:: --sudo

Run command via sudo.

Scan Roster Options

.. option:: --scan-ports=SSH_SCAN_PORTS

Comma-separated list of ports to scan in the scan roster.

.. option:: --scan-timeout=SSH_SCAN_TIMEOUT

Scanning socket timeout for the scan roster.

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/ssh
.. |loglevel| replace:: warning

.. include:: _includes/target-selection-ssh.rst

.. include:: _includes/output-options.rst

.. note::
If using --out=json, you will probably want --static as well.
Without the static option, you will get a separate JSON string per minion
which makes JSON output invalid as a whole.
This is due to using an iterative outputter. So if you want to feed it
to a JSON parser, use --static as well.

See also

:manpage:salt(7)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt Syndic (`doc/ref/cli/salt-syndic.rst`)

=============== ``salt-syndic``

The Salt syndic daemon, a special minion that passes through commands from a
higher master

Synopsis

.. code-block:: bash

text
salt-syndic [ options ]

Description

The Salt syndic daemon, a special minion that passes through commands from a
higher master.

Options

.. program:: salt-syndic

.. include:: _includes/common-options.rst

.. include:: _includes/daemon-options.rst
.. |salt-daemon| replace:: salt-syndic

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/master
.. |loglevel| replace:: warning

See also

:manpage:salt(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Salt (`doc/ref/cli/salt.rst`)

.. _ref-cli-salt:

======== ``salt``

Synopsis

text
salt '*' [ options ] sys.doc

salt -E '.*' [ options ] sys.doc cmd

salt -G 'os:Arch.*' [ options ] test.version

salt -C 'G@os:Arch.* and webserv* or G@kernel:FreeBSD' [ options ] test.version

Description

Salt allows for commands to be executed across a swath of remote systems in
parallel. This means that remote systems can be both controlled and queried
with ease.

Options

.. program:: salt

.. include:: _includes/common-options.rst

.. include:: _includes/timeout-option.rst
.. |timeout| replace:: 5

.. option:: -s, --static

text
By default as of version 0.9.8 the salt command returns data to the
console as it is received from minions, but previous releases would return
data only after all data was received. Use the static option to only return
the data with a hard timeout and after all minions have returned.
Without the static option, you will get a separate JSON string per minion
which makes JSON output invalid as a whole.

.. option:: --async

text
Instead of waiting for the job to run on minions only print the job id of
the started execution and complete.

.. option:: --subset=SUBSET

text
Execute the routine on a random subset of the targeted minions.  The
minions will be verified that they have the named function before
executing. The SUBSET argument is the count of the minions to target.

.. option:: -v VERBOSE, --verbose

text
Turn on verbosity for the salt call, this will cause the salt command to
print out extra data like the job id.

.. option:: --hide-timeout

text
Instead of showing the return data for all minions. This option
prints only the online minions which could be reached.

.. option:: -b BATCH, --batch-size=BATCH

text
Instead of executing on all targeted minions at once, execute on a
progressive set of minions. This option takes an argument in the form of
an explicit number of minions to execute at once, or a percentage of
minions to execute on.

.. option:: --batch-wait=BATCH_WAIT

Wait the specified time in seconds after each job is done before
freeing the slot in the batch of the next one.

.. option:: --batch-safe-limit=BATCH_SAFE_LIMIT

Execute the salt job in batch mode if the job would have executed
on at least this many minions.

.. option:: --batch-safe-size=BATCH_SAFE_SIZE

Batch size to use for batch jobs created by --batch-safe-limit.

.. option:: -a EAUTH, --auth=EAUTH

text
Pass in an external authentication medium to validate against. The
credentials will be prompted for. The options are `auto`,
`keystone`, `ldap`, and `pam`. Can be used with the -T
option.

.. option:: -T, --make-token

text
Used in conjunction with the -a option. This creates a token that allows
for the authenticated user to send commands without needing to
re-authenticate.

.. option:: --return=RETURNER

text
Choose an alternative returner to call on the minion, if an
alternative returner is used then the return will not come back to
the command line but will be sent to the specified return system.
The options are `carbon`, `cassandra`, `couchbase`, `couchdb`,
`elasticsearch`, `etcd`, `hipchat`, `local`, `local_cache`,
`memcache`, `mongo`, `mysql`, `odbc`, `postgres`, `redis`,
`sentry`, `slack`, `sms`, `smtp`, `sqlite3`, `syslog`, and `xmpp`.

.. option:: -d, --doc, --documentation

text
Return the documentation for the module functions available on the minions

.. option:: --args-separator=ARGS_SEPARATOR

text
Set the special argument used as a delimiter between command arguments of
compound commands. This is useful when one wants to pass commas as
arguments to some of the commands in a compound command.

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/master
.. |loglevel| replace:: warning

.. include:: _includes/target-selection.rst
.. include:: _includes/extended-target-selection.rst

.. include:: _includes/output-options.rst

.. note::
If using --out=json, you will probably want --static as well.
Without the static option, you will get a separate JSON string per minion
which makes JSON output invalid as a whole.
This is due to using an iterative outputter. So if you want to feed it
to a JSON parser, use --static as well.

See also

:manpage:salt(7)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Cli Spm (`doc/ref/cli/spm.rst`)

.. _spm-cli:

======= ``spm``

:ref:Salt Package Manager <spm>

Synopsis

.. code-block:: bash

text
spm <command> [<argument>]

Description

spm is the frontend command for managing Salt packages. Packages normally only
include formulas, meaning a group of SLS files that install into the
file_roots on the Salt Master, but Salt modules can also be installed.

Options

.. program:: spm

.. option:: -y, --assume-yes

text
Assume ``yes`` instead of prompting the other whether or not to proceed
with a particular command. Default is False.

.. option:: -f, --force

text
When presented with a course of action that spm would normally refuse to
perform, that action will be performed anyway. This is often destructive,
and should be used with caution.

.. include:: _includes/logging-options.rst
.. |logfile| replace:: /var/log/salt/spm
.. |loglevel| replace:: warning

Commands

.. program:: spm

.. option:: update_repo

text
Connect to remote repositories locally configured on the system and download
their metadata.

.. option:: install

text
Install a package from a configured SPM repository. Requires a package name.

.. option:: remove

text
Remove an installed package from the system. Requires a package name.

.. option:: info

text
List information about an installed package. Requires a package name.

.. option:: files

text
List files belonging to an installed package. Requires a package name.

.. option:: local

text
Perform one of the above options (except for remove) on a package file,
instead of on a package in a repository, or an installed package. Requires
a valid path to a local file on the system.

.. option:: build

text
Build a package from a directory containing a FORMULA file. Requires a valid
path to a local directory on the system.

.. option:: create_repo

text
Scan a directory for valid SPM package files and build an SPM-METADATA file
in that directory which describes them.

See also

:manpage:salt(1)
:manpage:salt-master(1)
:manpage:salt-minion(1)


Doc Ref Clients Index (`doc/ref/clients/index.rst`)

.. _client-apis:
.. _python-api:

================= Python client API

Salt provides several entry points for interfacing with Python applications.
These entry points are often referred to as *Client() APIs. Each client
accesses different parts of Salt, either from the master or from a minion. Each
client is detailed below.

.. note::
For Tiamat-bundled Salt distribution, you need to use the bundled Python runtime
as the system Python won't be able to access Salt internals.

text
To execute scripts via bundled Python runtime, either run the script with
``/path/to/salt python script.py`` or use ``#!/path/to/salt python`` `shebang <https://en.wikipedia.org/wiki/Shebang_(Unix)>`_

.. seealso:: There are many ways to access Salt programmatically.

text
Salt can be used from CLI scripts as well as via a REST interface.

See Salt's :ref:`outputter system <all-salt.output>` to retrieve structured
data from Salt as JSON, or as shell-friendly text, or many other formats.

See the :py:func:`state.event <salt.runners.state.event>` runner to utilize
Salt's event bus from shell scripts.

Salt's `netapi module`_ provides access to Salt externally via a REST interface.
Review the `netapi module`_ documentation for more information.

.. _netapi module: https://docs.saltproject.io/en/latest/topics/netapi/index.html

Salt's ``opts`` dictionary

Some clients require access to Salt's opts dictionary. (The dictionary
representation of the :ref:master <configuration-salt-master> or
:ref:minion <configuration-salt-minion> config files.)

A common pattern for fetching the opts dictionary is to defer to
environment variables if they exist or otherwise fetch the config from the
default location.

.. autofunction:: salt.config.client_config

.. autofunction:: salt.config.minion_config

Salt's Loader Interface

Modules in the Salt ecosystem are loaded into memory using a custom loader
system. This allows modules to have conditional requirements (OS, OS version,
installed libraries, etc) and allows Salt to inject special variables
(__salt__, __opts__, etc).

Most modules can be manually loaded. This is often useful in third-party Python
apps or when writing tests. However some modules require and expect a full,
running Salt system underneath. Notably modules that facilitate
master-to-minion communication such as the :py:mod:~salt.modules.mine,
:py:mod:~salt.modules.publish, and :py:mod:~salt.modules.peer execution
modules. The error KeyError: 'master_uri' is a likely indicator for this
situation. In those instances use the :py:class:~salt.client.Caller class
to execute those modules instead.

Each module type has a corresponding loader function.

.. autofunction:: salt.loader.minion_mods

.. autofunction:: salt.loader.raw_mod

.. autofunction:: salt.loader.states

.. autofunction:: salt.loader.grains

.. autofunction:: salt.loader.grain_funcs

Salt's Client Interfaces

.. _client-interfaces:
.. _local-client:

LocalClient

.. autoclass:: salt.client.LocalClient
:members: cmd, run_job, cmd_async, cmd_subset, cmd_batch, cmd_iter,
cmd_iter_no_block, get_cli_returns, get_event_iter_returns

Salt Caller

.. autoclass:: salt.client.Caller
:members: cmd

Salt Proxy Caller

.. autoclass:: salt.client.ProxyCaller
:members: cmd

RunnerClient

.. autoclass:: salt.runner.RunnerClient
:members: cmd, asynchronous, cmd_sync, cmd_async

WheelClient

.. autoclass:: salt.wheel.WheelClient
:members: cmd, asynchronous, cmd_sync, cmd_async

CloudClient

.. autoclass:: salt.cloud.CloudClient
:members:

SSHClient

.. autoclass:: salt.client.ssh.client.SSHClient
:members: cmd, cmd_iter


Doc Ref Configuration Delta Proxy (`doc/ref/configuration/delta_proxy.rst`)

.. _delta-proxy-information:

.. _delta-proxy-intro:

=================== Delta proxy minions

Welcome to the delta proxy minion installation guide. This installation
guide explains the process for installing and using delta proxy minion
which is available beginning in version 3004.

This guide is intended for system and network administrators with the general
knowledge and experience required in the field. This guide is also intended for
users that have ideally already tested and used standard Salt proxy minions in
their environment before deciding to move to a delta proxy minion environment.
See Salt proxy minions <https://docs.saltproject.io/en/latest/topics/proxyminion/index.html>_ for more information.

.. Note::
If you have not used standard Salt proxy minions before, consider testing
and deploying standard Salt proxy minions in your environment first.

Proxy minions vs. delta proxy minions

Salt can target network devices through Salt proxy minions <https://docs.saltproject.io/en/latest/topics/proxyminion/index.html>_,
Proxy minions allow you to control network devices that, for whatever reason,
cannot run the standard Salt minion. Examples include:

  • Network gear that has an API but runs a proprietary operating system
  • Devices with limited CPU or memory
  • Devices that could run a minion but will not for security reasons

A proxy minion acts as an intermediary between the Salt master and the
device it represents. The proxy minion runs on the Salt master and then
translates commands from the Salt master to the device as needed.

By acting as an intermediary for the actual minion, proxy minions eliminate
the need to establish a constant connection from a Salt master to a minion. Proxy
minions generally only open a connection to the actual minion when necessary.

Proxy minions also reduce the amount of CPU or memory the minion must spend
checking for commands from the Salt master. Proxy minions use the Salt master's CPU
or memory to check for commands. The actual minion only needs to use CPU or
memory to run commands when needed.

.. Note::
For more information about Salt proxy minions, see:

text
* `Salt proxy minions
  <https://docs.saltproject.io/en/latest/topics/proxyminion/index.html>`_

* `Salt proxy modules
  <https://docs.saltproject.io/en/latest/ref/proxy/all/index.html#all-salt-proxy>`_

When delta proxy minions are needed

Normally, you would create a separate instance of proxy minion for each device
that needs to be managed. However, this doesn't always scale well if you have
thousands of devices. Running several thousand proxy minions can require a lot
of memory and CPU.

A delta proxy minion can solve this problem: it makes it possible to run one
minion that acts as the intermediary between the Salt master and the many network
devices it can represent. In this scenario, one device (the delta proxy minion
on the Salt master) runs several proxies. This configuration boosts performance and
improves the overall scalability of the network.

Key terms

The following lists some important terminology that is used throughout this
guide:

.. list-table::
:widths: 25 75
:header-rows: 1

    • Term
    • Definition
    • Salt master
    • The Salt master is a central node running the Salt master server.
      The Salt master issues commands to minions.
    • minion
    • Minions are nodes running the Salt minion service. Minions listen
      to commands from a Salt master and perform the requested tasks, then return
      data back to the Salt master as needed.
    • proxy minion
    • A Salt master that is running the proxy-minion service. The proxy minion
      acts as an intermediary between the Salt master and the device it represents.
      The proxy minion runs on the Salt master and then translates commands from
      the Salt master to the device. A separate instance of proxy minion is
      needed for each device that is managed.
    • delta proxy minion
    • A Salt master that is running the delta proxy-minion service. The
      delta proxy minion acts as the intermediary between the Salt master and the
      many network devices it can represent. Only one instance of the delta
      proxy service is needed to run several proxies.
    • control proxy
    • The control proxy runs on the Salt master. It manages a list of devices and
      issues commands to the network devices it represents. The Salt master needs
      at least one control proxy, but it is possible to have more than one
      control proxy, each managing a different set of devices.
    • managed device
    • A device (such as Netmiko) that is managed by proxy minions or by a
      control proxy minion. The proxy minion or control proxy only creates
      a connection to the actual minion it needs to issue a command.
    • pillar file
    • Pillars are structures of data (files) defined on the Salt master and passed
      through to one or more minions when the minion needs access to the
      pillar file. Pillars allow confidential, targeted data to be securely sent
      only to the relevant minion. Because all configurations for
      delta proxy minions are done on the Salt master (not on the minions), you
      use pillar files to configure the delta proxy-minion service.
    • top file
    • The top file is a pillar file that maps which states should be applied to
      different minions in certain environments.

.. _delta-proxy-preinstall:

Pre-installation

Before you start

Before installing the delta proxy minion, ensure that:

  • Your network device and firmware are supported.
  • The Salt master that is acting as the control proxy minion has network
    access to the devices it is managing.
  • You have installed, configured, and tested standard Salt proxy minions in
    your environment before introducing delta proxy minions into your
    environment.

Install or upgrade Salt

Ensure your Salt masters are running at least Salt version 3004. For instructions
on installing or upgrading Salt, see the
Salt Install Guide <https://docs.saltproject.io/salt/install-guide/en/latest/>_.

.. _delta-proxy-install:

Installation

Before you begin the delta proxy minion installation process, ensure you
have read and completed the :ref:delta-proxy-preinstall steps.

Overview of the installation process

Similar to proxy minions, all the delta proxy minion configurations are done
on the Salt master rather than on the minions that will be managed. The
installation process has the following phases:

#. Configure the master to use delta proxy_ - Create a
configuration file on the Salt master that defines its proxy settings.
#. Create a pillar file for each managed device_ - Create a
pillar file for each device that will be managed by the delta proxy minion
and reference these minions in the top file.
#. Create a control proxy configuration file_ - Create a control proxy file
that lists the devices that it will manage. Then, reference this file in the
top file.
#. Start the delta proxy minion_ - Start the delta proxy-minion service and
validate that it has been set up correctly.

Configure the master to use delta proxy

In this step, you'll create a configuration file on the Salt master that defines
its proxy settings. This is a general configuration file that tells the Salt master
how to handle all proxy minions.

To create this configuration:

#. On the Salt master, navigate to the /etc/salt directory. In this directory,
create a file named proxy if one doesn't already exist.

#. Open the file in your preferred editor and add the following configuration
information:

.. code-block:: yaml

text
# Use delta proxy metaproxy
   metaproxy: deltaproxy

   # Disable the FQDNS grain
   enable_fqdns_grains: False

   # Enabled multprocessing
   multiprocessing: True

.. Note::
See the following section about delta proxy configuration options_ for
a more detailed description of these configuration options.

#. Save the file.

Your Salt master is now configured to use delta proxy. Next, you need to
Create a pillar file for each managed device_.

Delta proxy configuration options

The following table describes the configuration options used in the delta
proxy configuration file:

.. list-table::
:widths: 25 75
:header-rows: 1

    • Field
    • Description
    • metaproxy
    • Set this configuration option to deltaproxy. If this option is set to
      proxy or if this line is not included in the file, the Salt master will
      use the standard proxy service instead of the delta proxy service.
    • enable_fqdns_grains
    • If your router does not have the ability to use Reverse DNS lookup to
      obtain the Fully Qualified Domain Name (fqdn) for an IP address, you'll
      need to change the enable_fqdns_grains setting in the pillar
      configuration file to False instead.
    • multiprocessing

    • Multi-processing is the ability to run more than one task or process at
      the same time. A delta proxy minion has the ability to run with
      multi-processing turned off.

      If you plan to run with multi-processing enabled, you should also enable
      the skip_connect_on_init setting to True.

    • skip_connect_on_init
    • This setting tells the control proxy whether or not it should make a
      connection to the managed device when it starts. When set to True, the
      delta proxy minion will only connect when it needs to issue commands to
      the managed devices.

Create a pillar file for each managed device

Each device that needs to be managed by delta proxy needs a separate pillar
file on the Salt master. To create this file:

#. Navigate to the /srv/pillar directory.

#. In this directory create a new pillar file for a minion. For example,
my_managed_device_pillar_file_01.sls.

#. Open the new file in your preferred editor and add the necessary
configuration information for that minion and your environment. The
following is an example pillar file for a Netmiko device:

.. code-block:: yaml

text
proxy:
     proxytype: netmiko
     device_type: arista_eos
     host: 192.0.2.1
     username: myusername
     password: mypassword
     always_alive: True

.. Note::
The available configuration options vary depending on the proxy type (in
other words, the type of device it is). To read a detailed explanation of
the configuration options, refer to the proxy module documentation for
the type of device you need to manage. See:

text
* `Salt proxy modules
    <https://docs.saltproject.io/en/latest/ref/proxy/all/index.html#all-salt-proxy>`_
  * `Netmiko Salt proxy module
    <https://docs.saltproject.io/en/latest/ref/proxy/all/salt.proxy.netmiko_px.html#module-salt.proxy.netmiko_px>`_

#. Save the file.

#. In an editor, open the top file: /srv/pillar/top.sls.

#. Add a section to the top file that indicates the minion ID of the device
that will be managed. Then, list the name of the pillar file you created in
the previous steps. For example:

.. code-block:: yaml

text
my_managed_device_minion_ID:
     - my_managed_device_pillar_file_01

#. Repeat the previous steps for each minion that needs to be managed.

You've now created the pillar file for the minions that will be managed by the
delta proxy minion and you have referenced these files in the top file.
Proceed to the next section.

Create a control proxy configuration file

On the Salt master, you'll need to create or edit a control proxy file for each
control proxy. The control proxy manages several devices and issues commands to
the network devices it represents. The Salt master needs at least one control
proxy, but it is possible to have more than one control proxy, each managing a
different set of devices.

To configure a control proxy, you'll create a file that lists the minion IDs
of the minions that it will manage. Then you will reference this control proxy
configuration file in the top file.

To create a control proxy configuration file:

#. On the Salt master, navigate to the /srv/pillar directory. In this
directory, create a new proxy configuration file. Give this file a
descriptive name, such as control_proxy_01_configuration.sls.

#. Open the file in your preferred editor and add a list of the minion IDs for
each device that needs to be managed. For example:

.. code-block:: yaml

text
proxy:
     proxytype: deltaproxy
     ids:
       - my_managed_device_01
       - my_managed_device_02
       - my_managed_device_03

#. Save the file.

#. In an editor, open the top file: /srv/pillar/top.sls.

#. Add a section to the top file that indicates references the delta proxy
control proxy. For example:

.. code-block:: yaml

text
base:
     my_managed_device_minion_01:
       - my_managed_device_pillar_file_01
     my_managed_device_minion_02:
       - my_managed_device_pillar_file_02
     my_managed_device_minion_03:
       - my_managed_device_pillar_file_03
     delta_proxy_control:
       - control_proxy_01_configuration

#. Repeat the previous steps for each control proxy if needed.

#. In an editor, open the proxy config file: /etc/salt/proxy.
Add a section for metaproxy and set it's value to deltaproxy.

.. code-block:: yaml

text
metaproxy: deltaproxy

Now that you have created the necessary configurations, proceed to the next
section.

Start the delta proxy minion

After you've successfully configured the delta proxy minion, you need to
start the proxy minion service for each managed device and validate that it is
working correctly.

.. Note::
This step explains the process for starting a single instance of a
delta proxy minion. Because starting each minion individually can
potentially be very time-consuming, most organizations use a script to start
their delta proxy minions since there are typically many devices being
managed. Consider implementing a similar script for your environment to save
time in deployment.

To start a single instance of a delta proxy minion and test that it is
configured correctly:

#. In the terminal for the Salt master, run the following command, replacing the
placeholder text with the actual minion ID:

.. code-block:: bash

text
sudo salt-proxy --proxyid=<control_proxy_id>

#. To test the delta proxy minion, run the following test.version command
on the Salt master and target a specific minion. For example:

.. code-block:: bash

text
salt my_managed_device_minion_ID test.version

This command returns an output similar to the following:

.. code-block:: bash

text
local:
       3004

After you've successfully started the delta proxy minions and verified that
they are working correctly, you can now use these minions the same as standard
proxy minions.

.. _delta-proxy-additional-resources:

Additional resources

This reference section includes additional resources for delta proxy minions.

For reference, see:

  • Salt proxy minions <https://docs.saltproject.io/en/latest/topics/proxyminion/index.html>_

  • Salt proxy modules <https://docs.saltproject.io/en/latest/ref/proxy/all/index.html#all-salt-proxy>_

  • Netmiko Salt proxy module <https://docs.saltproject.io/en/latest/ref/proxy/all/salt.proxy.netmiko_px.html#module-salt.proxy.netmiko_px>_


Doc Ref Configuration Examples (`doc/ref/configuration/examples.rst`)

.. _configuration-file-examples:

=========================== Configuration file examples

.. _configuration-examples-master:

.. contents::
:local:
:depth: 1

Example master configuration file

.. literalinclude:: ../../../conf/master
:language: yaml

.. _configuration-examples-minion:

Example minion configuration file

.. literalinclude:: ../../../conf/minion
:language: yaml

.. _configuration-examples-proxy:

Example proxy minion configuration file

.. literalinclude:: ../../../conf/proxy
:language: yaml


Doc Ref Configuration Index (`doc/ref/configuration/index.rst`)

.. _configuring-salt:

================ Configuring Salt

Salt configuration is very simple. The default configuration for the
:term:master <Master> will work for most installations and the only requirement for
setting up a :term:minion <Minion> is to set the location of the master in the minion
configuration file.

The configuration files will be installed to :file:/etc/salt and are named
after the respective components, :file:/etc/salt/master, and
:file:/etc/salt/minion.

Master Configuration

By default the Salt master listens on ports 4505 and 4506 on all
interfaces (0.0.0.0). To bind Salt to a specific IP, redefine the
"interface" directive in the master configuration file, typically
/etc/salt/master, as follows:

.. code-block:: diff

  • #interface: 0.0.0.0
  • interface: 10.0.0.1

After updating the configuration file, restart the Salt master.
See the :ref:master configuration reference <configuration-salt-master>
for more details about other configurable options.

Minion Configuration

Although there are many Salt Minion configuration options, configuring
a Salt Minion is very simple. By default a Salt Minion will
try to connect to the DNS name "salt"; if the Minion is able to
resolve that name correctly, no configuration is needed.

If the DNS name "salt" does not resolve to point to the correct
location of the Master, redefine the "master" directive in the minion
configuration file, typically /etc/salt/minion, as follows:

.. code-block:: diff

  • #master: salt
  • master: 10.0.0.1

After updating the configuration file, restart the Salt minion.
See the :ref:minion configuration reference <configuration-salt-minion>
for more details about other configurable options.

Proxy Minion Configuration

A proxy minion emulates the behaviour of a regular minion
and inherits their options.

Similarly, the configuration file is /etc/salt/proxy and the proxy
tries to connect to the DNS name "salt".

In addition to the regular minion options,
there are several proxy-specific - see the
:ref:proxy minion configuration reference <configuration-salt-proxy>.

Running Salt

  1. Start the master in the foreground (to daemonize the process, pass the
    :option:-d flag <salt-master -d>):

    .. code-block:: bash

    text
    salt-master
  2. Start the minion in the foreground (to daemonize the process, pass the
    :option:-d flag <salt-minion -d>):

    .. code-block:: bash

    text
    salt-minion

.. admonition:: Having trouble?

text
The simplest way to troubleshoot Salt is to run the master and minion in
the foreground with :option:`log level <salt-master -l>` set to ``debug``:

.. code-block:: bash

    salt-master --log-level=debug

For information on salt's logging system please see the :ref:`logging
document<logging>`.

.. admonition:: Run as an unprivileged (non-root) user

text
To run Salt as another user, set the :conf_master:`user` parameter in the
master config file.

Additionally, ownership, and permissions need to be set such that the
desired user can read from and write to the following directories (and
their subdirectories, where applicable):

* /etc/salt
* /var/cache/salt
* /var/log/salt
* /var/run/salt

More information about running salt as a non-privileged user can be found
:ref:`here <configuration-non-root-user>`.

There is also a full :ref:troubleshooting guide
available.

.. _key-identity:

Key Identity

Salt provides commands to validate the identity of your Salt master
and Salt minions before the initial key exchange. Validating key identity helps
avoid inadvertently connecting to the wrong Salt master, and helps prevent
a potential MiTM attack when establishing the initial connection.

Master Key Fingerprint

Print the master key fingerprint by running the following command on the Salt master:

.. code-block:: bash

salt-key -F master

Copy the master.pub fingerprint from the Local Keys section, and then set this value
as the :conf_minion:master_finger in the minion configuration file. Save the configuration
file and then restart the Salt minion.

Minion Key Fingerprint

Run the following command on each Salt minion to view the minion key fingerprint:

.. code-block:: bash

salt-call --local key.finger

Compare this value to the value that is displayed when you run the
salt-key --finger <MINION_ID> command on the Salt master.

Key Management

Salt uses AES encryption for all communication between the Master and
the Minion. This ensures that the commands sent to the Minions cannot
be tampered with, and that communication between Master and Minion is
authenticated through trusted, accepted keys.

Before commands can be sent to a Minion, its key must be accepted on
the Master. Run the salt-key command to list the keys known to
the Salt Master:

.. code-block:: bash

[root@master ~]# salt-key -L
Unaccepted Keys:
alpha
bravo
charlie
delta
Accepted Keys:

This example shows that the Salt Master is aware of four Minions, but none of
the keys has been accepted. To accept the keys and allow the Minions to be
controlled by the Master, again use the salt-key command:

.. code-block:: bash

[root@master ~]# salt-key -A
[root@master ~]# salt-key -L
Unaccepted Keys:
Accepted Keys:
alpha
bravo
charlie
delta

The salt-key command allows for signing keys individually or in bulk. The
example above, using -A bulk-accepts all pending keys. To accept keys
individually use the lowercase of the same option, -a keyname.

.. seealso:: :ref:salt-key manpage <salt-key>

Sending Commands

Communication between the Master and a Minion may be verified by running
the test.version command:

.. code-block:: bash

[root@master ~]# salt alpha test.version
alpha:
2018.3.4

Communication between the Master and all Minions may be tested in a
similar way:

.. code-block:: bash

[root@master ~]# salt '*' test.version
alpha:
2018.3.4
bravo:
2018.3.4
charlie:
2018.3.4
delta:
2018.3.4

Each of the Minions should send a 2018.3.4 response as shown above,
or any other salt version installed.

What's Next?

Understanding :ref:targeting <targeting> is important. From there, depending
on the way you wish to use Salt, you should also proceed to learn about
:ref:Remote Execution <remote-execution> and :ref:Configuration Management <configuration-management>.


Doc Ref Configuration Master (`doc/ref/configuration/master.rst`)

.. _configuration-salt-master:

=========================== Configuring the Salt Master

The Salt system is amazingly simple and easy to configure, the two components
of the Salt system each have a respective configuration file. The
salt-master is configured via the master configuration file, and the
salt-minion is configured via the minion configuration file.

.. seealso::

text
:ref:`Example master configuration file <configuration-examples-master>`.

The configuration file for the salt-master is located at /etc/salt/master
by default. Atomic included configuration files can be placed in
/etc/salt/master.d/*.conf. Warning: files with other suffixes than .conf will
not be included. A notable exception is FreeBSD, where the configuration file is
located at /usr/local/etc/salt. The available options are as follows:

.. _primary-master-configuration:

Primary Master Configuration

.. conf_master:: interface

``interface``

Default: 0.0.0.0 (all interfaces)

The local interface to bind to, must be an IP address.

.. code-block:: yaml

text
interface: 192.168.0.1

.. conf_master:: ipv6

``ipv6``

Default: False

Whether the master should listen for IPv6 connections. If this is set to True,
the interface option must be adjusted too (for example: interface: '::').

When enabled, Salt also uses the IPv6 loopback address (::1) for internal
IPC connections between daemon processes instead of 127.0.0.1. On Windows,
this is required because Windows does not permit binding an AF_INET6 socket
to an IPv4 address.

.. code-block:: yaml

text
ipv6: True

.. conf_master:: publish_port

``publish_port``

Default: 4505

The network port to set up the publication interface.

.. code-block:: yaml

text
publish_port: 4505

.. conf_master:: master_id

``master_id``

Default: None

The id to be passed in the publish job to minions. This is used for MultiSyndics
to return the job to the requesting master.

.. note::

text
This must be the same string as the syndic is configured with.

.. code-block:: yaml

text
master_id: MasterOfMaster

.. conf_master:: user

``user``

Default: root

The user to run the Salt processes

.. code-block:: yaml

text
user: root

.. note::

text
Starting with version `3006.0`, Salt's offical packages ship with a default
configuration which runs the Master as a non-priviledged user. The Master's
configuration file has the `user` option set to `user: salt`. Unless you
are absolutly sure want to run salt as some other user, care should be
taken to preserve this setting in your Master configuration file..

.. conf_master:: ret_port

``enable_ssh_minions``

Default: False

Tell the master to also use salt-ssh when running commands against minions.

.. code-block:: yaml

text
enable_ssh_minions: True

.. note::

text
Enabling this does not influence the limitations on cross-minion communication.
The Salt mine and ``publish.publish`` do not work from regular minions
to SSH minions, the other way around is partly possible since 3007.0
(during state rendering on the master).
This means you can use the mentioned functions to call out to regular minions
in ``sls`` templates and wrapper modules, but state modules
(which are executed on the remote) relying on them still do not work.

``ret_port``

Default: 4506

The port used by the return server, this is the server used by Salt to receive
execution returns and command executions.

.. code-block:: yaml

text
ret_port: 4506

.. conf_master:: pidfile

``pidfile``

Default: /var/run/salt-master.pid

Specify the location of the master pidfile.

.. code-block:: yaml

text
pidfile: /var/run/salt-master.pid

.. conf_master:: root_dir

``root_dir``

Default: /

The system root directory to operate from, change this to make Salt run from
an alternative root.

.. code-block:: yaml

text
root_dir: /

.. note::

text
This directory is prepended to the following options:
:conf_master:`pki_dir`, :conf_master:`cachedir`, :conf_master:`sock_dir`,
:conf_master:`log_file`, :conf_master:`autosign_file`,
:conf_master:`autoreject_file`, :conf_master:`pidfile`,
:conf_master:`autosign_grains_dir`.

.. conf_master:: conf_file

``conf_file``

Default: /etc/salt/master

The path to the master's configuration file.

.. code-block:: yaml

text
conf_file: /etc/salt/master

.. conf_master:: pki_dir

``pki_dir``

Default: <LIB_STATE_DIR>/pki/master

The directory to store the pki authentication keys.

<LIB_STATE_DIR> is the pre-configured variable state directory set during
installation via --salt-lib-state-dir. It defaults to /etc/salt. Systems
following the Filesystem Hierarchy Standard (FHS) might set it to
/var/lib/salt.

.. code-block:: yaml

text
pki_dir: /etc/salt/pki/master

.. conf_master:: cluster_id

``cluster_id``

.. versionadded:: 3007

When defined, the master will operate in cluster mode. The master will send the
cluster key and id to minions instead of its own key and id. The master will
also forward its local event bus to other masters defined by cluster_peers

.. code-block:: yaml

text
cluster_id: master_cluster

.. conf_master:: cluster_peers

``cluster_peers``

.. versionadded:: 3007

When cluster_peers is defined, this setting is a list of other master
(hostnames or IPs) that will be in the cluster.

.. code-block:: yaml

text
cluster_peers:
   - master2
   - master3

.. conf_master:: cluster_pki_dir

``cluster_pki_dir``

.. versionadded:: 3007

When cluster_pki_dir is defined, this sets the location of where this
cluster will store its cluster public and private key as well as any minion
keys. This setting will default to the value of pki_dir, but should be
changed to the filesystem location shared between peers in the cluster.

.. code-block:: yaml

text
cluster_pki_dir: /my/gluster/share/pki

.. conf_master:: cluster_pool_port

``cluster_pool_port``

.. versionadded:: 3007.2

When cluster_pool_port is defined, it sets the TCP port number HAProxy
listens on for incoming TCP connections. The default is 4520

.. code-block:: yaml

text
cluster_pool_port: 4520

.. conf_master:: extension_modules

``extension_modules``

.. versionchanged:: 2016.3.0

text
The default location for this directory has been moved. Prior to this
version, the location was a directory named ``extmods`` in the Salt
cachedir (on most platforms, ``/var/cache/salt/extmods``). It has been
moved into the master cachedir (on most platforms,
``/var/cache/salt/master/extmods``).

Directory where custom modules are synced to. This directory can contain
subdirectories for each of Salt's module types such as runners,
output, wheel, modules, states, returners, engines,
utils, etc. This path is appended to :conf_master:root_dir.

Note, any directories or files not found in the module_dirs location
will be removed from the extension_modules path.

.. code-block:: yaml

text
extension_modules: /root/salt_extmods

.. conf_master:: extmod_whitelist
.. conf_master:: extmod_blacklist

``extmod_whitelist/extmod_blacklist``

.. versionadded:: 2017.7.0

By using this dictionary, the modules that are synced to the master's extmod cache using saltutil.sync_* can be
limited. If nothing is set to a specific type, then all modules are accepted. To block all modules of a specific type,
whitelist an empty list.

.. code-block:: yaml

text
extmod_whitelist:
  modules:
    - custom_module
  engines:
    - custom_engine
  pillars: []

extmod_blacklist:
  modules:
    - specific_module

Valid options:

  • modules
  • states
  • grains
  • renderers
  • returners
  • output
  • proxy
  • runners
  • wheel
  • engines
  • queues
  • pillar
  • utils
  • sdb
  • cache
  • clouds
  • tops
  • roster
  • tokens

.. conf_master:: module_dirs

``module_dirs``

Default: []

Like extension_modules, but a list of extra directories to search
for Salt modules.

.. code-block:: yaml

text
module_dirs:
  - /var/cache/salt/minion/extmods

.. conf_master:: cachedir

``cachedir``

Default: /var/cache/salt/master

The location used to store cache information, particularly the job information
for executed salt commands.

This directory may contain sensitive data and should be protected accordingly.

.. code-block:: yaml

text
cachedir: /var/cache/salt/master

.. conf_master:: verify_env

``verify_env``

Default: True

Verify and set permissions on configuration directories at startup.

.. code-block:: yaml

text
verify_env: True

.. conf_master:: keep_jobs

``keep_jobs``

Default: 24

Set the number of hours to keep old job information. Note that setting this option
to 0 disables the cache cleaner.

.. deprecated:: 3006
Replaced by :conf_master:keep_jobs_seconds

.. code-block:: yaml

text
keep_jobs: 24

.. conf_master:: keep_jobs_seconds

``keep_jobs_seconds``

Default: 86400

Set the number of seconds to keep old job information. Note that setting this option
to 0 disables the cache cleaner.

.. code-block:: yaml

text
keep_jobs_seconds: 86400

.. conf_master:: gather_job_timeout

``gather_job_timeout``

.. versionadded:: 2014.7.0

Default: 10

The number of seconds to wait when the client is requesting information
about running jobs.

.. code-block:: yaml

text
gather_job_timeout: 10

.. conf_master:: timeout

``timeout``

Default: 5

Set the default timeout for the salt command and api.

.. conf_master:: loop_interval

.. conf_minion:: ipc_write_timeout

``ipc_write_timeout``

.. versionadded:: 3006.11

Default: 15

How many seconds the event publisher process will wait after a client stops
responding before the client will be disconnected.

.. code-block:: yaml

text
ipc_write_timeout: 15

``loop_interval``

Default: 60

The loop_interval option controls the seconds for the master's Maintenance
process check cycle. This process updates file server backends, cleans the
job cache and executes the scheduler.

``maintenance_interval``

.. versionadded:: 3006.0

Default: 3600

Defines how often to restart the master's Maintenance process.

.. code-block:: yaml

text
maintenance_interval: 9600

.. note::

text
Scheduled jobs will fail to trigger if their interval is greater than the
``maintenance_interval``. Because the master scheduler only evaluates jobs
during maintenance cycles, a default 3600-second (1-hour) maintenance
interval will effectively ignore any job set to run every 7200 seconds (2
hours).

.. conf_master:: output

``output``

Default: nested

Set the default outputter used by the salt command.

.. conf_master:: outputter_dirs

``outputter_dirs``

Default: []

A list of additional directories to search for salt outputters in.

.. code-block:: yaml

text
outputter_dirs: []

.. conf_master:: output_file

``output_file``

Default: None

Set the default output file used by the salt command. Default is to output
to the CLI and not to a file. Functions the same way as the "--out-file"
CLI option, only sets this to a single file for all salt commands.

.. code-block:: yaml

text
output_file: /path/output/file

.. conf_master:: show_timeout

``show_timeout``

Default: True

Tell the client to show minions that have timed out.

.. code-block:: yaml

text
show_timeout: True

.. conf_master:: show_jid

``show_jid``

Default: False

Tell the client to display the jid when a job is published.

.. code-block:: yaml

text
show_jid: False

.. conf_master:: color

``color``

Default: True

By default output is colored, to disable colored output set the color value
to False.

.. code-block:: yaml

text
color: False

.. conf_master:: color_theme

``color_theme``

Default: ""

Specifies a path to the color theme to use for colored command line output.

.. code-block:: yaml

text
color_theme: /etc/salt/color_theme

.. conf_master:: cli_summary

``cli_summary``

Default: False

When set to True, displays a summary of the number of minions targeted,
the number of minions returned, and the number of minions that did not
return.

.. code-block:: yaml

text
cli_summary: False

.. conf_master:: sock_dir

``sock_dir``

Default: :file:/var/run/salt/master

Set the location to use for creating Unix sockets for master process
communication.

.. code-block:: yaml

text
sock_dir: /var/run/salt/master

.. conf_master:: enable_gpu_grains

``enable_gpu_grains``

Default: False

Enable GPU hardware data for your master. Be aware that the master can
take a while to start up when lspci and/or dmidecode is used to populate the
grains for the master.

.. code-block:: yaml

text
enable_gpu_grains: True

.. conf_master:: skip_grains

``skip_grains``

Default: False

MasterMinions should omit grains. A MasterMinion is "a minion function object
for generic use on the master" that omit pillar. A RunnerClient creates a
MasterMinion omitting states and renderer. Setting to True can improve master
performance.

.. code-block:: yaml

text
skip_grains: True

.. conf_master:: job_cache

``job_cache``

Default: True

The master maintains a temporary job cache. While this is a great addition, it
can be a burden on the master for larger deployments (over 5000 minions).
Disabling the job cache will make previously executed jobs unavailable to
the jobs system and is not generally recommended. Normally it is wise to make
sure the master has access to a faster IO system or a tmpfs is mounted to the
jobs dir.

.. code-block:: yaml

text
job_cache: True

.. note::

text
Setting the ``job_cache`` to ``False`` will not cache minion returns, but
the JID directory for each job is still created. The creation of the JID
directories is necessary because Salt uses those directories to check for
JID collisions. By setting this option to ``False``, the job cache
directory, which is ``/var/cache/salt/master/jobs/`` by default, will be
smaller, but the JID directories will still be present.

Note that the :conf_master:`keep_jobs_seconds` option can be set to a lower
value, such as ``3600``, to limit the number of seconds jobs are stored in
the job cache. (The default is 86400 seconds.)

Please see the :ref:`Managing the Job Cache <managing_the_job_cache>`
documentation for more information.

.. conf_master:: minion_data_cache

``minion_data_cache``

Default: True

The minion data cache is a cache of information about the minions stored on the
master, this information is primarily the pillar, grains and mine data. The data
is cached via the cache subsystem in the Master cachedir under the name of the
minion or in a supported database. The data is used to predetermine what minions
are expected to reply from executions.

.. code-block:: yaml

text
minion_data_cache: True

.. conf_master:: cache

``cache``

Default: localfs

Cache subsystem module to use for minion data cache.

.. code-block:: yaml

text
cache: consul

.. conf_master:: memcache_expire_seconds

``memcache_expire_seconds``

Default: 0

Memcache is an additional cache layer that keeps a limited amount of data
fetched from the minion data cache for a limited period of time in memory that
makes cache operations faster. It doesn't make much sense for the localfs
cache driver but helps for more complex drivers like consul.

This option sets the memcache items expiration time. By default is set to 0
that disables the memcache.

.. code-block:: yaml

text
memcache_expire_seconds: 30

.. conf_master:: memcache_max_items

``memcache_max_items``

Default: 1024

Set memcache limit in items that are bank-key pairs. I.e the list of
minion_0/data, minion_0/mine, minion_1/data contains 3 items. This value depends
on the count of minions usually targeted in your environment. The best one could
be found by analyzing the cache log with memcache_debug enabled.

.. code-block:: yaml

text
memcache_max_items: 1024

.. conf_master:: memcache_full_cleanup

``memcache_full_cleanup``

Default: False

If cache storage got full, i.e. the items count exceeds the
memcache_max_items value, memcache cleans up its storage. If this option
set to False memcache removes the only one oldest value from its storage.
If this set set to True memcache removes all the expired items and also
removes the oldest one if there are no expired items.

.. code-block:: yaml

text
memcache_full_cleanup: True

.. conf_master:: memcache_debug

``memcache_debug``

Default: False

Enable collecting the memcache stats and log it on debug log level. If enabled
memcache collect information about how many fetch calls has been done and
how many of them has been hit by memcache. Also it outputs the rate value that
is the result of division of the first two values. This should help to choose
right values for the expiration time and the cache size.

.. code-block:: yaml

text
memcache_debug: True

.. conf_master:: ext_job_cache

``ext_job_cache``

Default: ''

Used to specify a default returner for all minions. When this option is set,
the specified returner needs to be properly configured and the minions will
always default to sending returns to this returner. This will also disable the
local job cache on the master.

.. code-block:: yaml

text
ext_job_cache: redis

.. conf_master:: event_return

``event_return``

.. versionadded:: 2015.5.0

Default: ''

Specify the returner(s) to use to log events. Each returner may have
installation and configuration requirements. Read the returner's
documentation.

.. note::

Not all returners support event returns. Verify that a returner has an
event_return() function before configuring this option with a returner.

.. code-block:: yaml

text
event_return:
  - syslog
  - splunk

.. conf_master:: event_return_queue

``event_return_queue``

.. versionadded:: 2015.5.0

Default: 0

On busy systems, enabling event_returns can cause a considerable load on
the storage system for returners. Events can be queued on the master and
stored in a batched fashion using a single transaction for multiple events.
By default, events are not queued.

.. code-block:: yaml

text
event_return_queue: 0

.. conf_master:: event_return_whitelist

``event_return_whitelist``

.. versionadded:: 2015.5.0

Default: []

Only return events matching tags in a whitelist.

.. versionchanged:: 2016.11.0

text
Supports glob matching patterns.

.. code-block:: yaml

text
event_return_whitelist:
  - salt/master/a_tag
  - salt/run/*/ret

.. conf_master:: event_return_blacklist

``event_return_blacklist``

.. versionadded:: 2015.5.0

Default: []

Store all event returns except the tags in a blacklist.

.. versionchanged:: 2016.11.0

text
Supports glob matching patterns.

.. code-block:: yaml

text
event_return_blacklist:
  - salt/master/not_this_tag
  - salt/wheel/*/ret

.. conf_master:: max_event_size

``max_event_size``

.. versionadded:: 2014.7.0

Default: 1048576

Passing very large events can cause the minion to consume large amounts of
memory. This value tunes the maximum size of a message allowed onto the
master event bus. The value is expressed in bytes.

.. code-block:: yaml

text
max_event_size: 1048576

.. conf_master:: master_job_cache

``master_job_cache``

.. versionadded:: 2014.7.0

Default: local_cache

Specify the returner to use for the job cache. The job cache will only be
interacted with from the salt master and therefore does not need to be
accessible from the minions.

.. code-block:: yaml

text
master_job_cache: redis

.. conf_master:: job_cache_store_endtime

``job_cache_store_endtime``

.. versionadded:: 2015.8.0

Default: False

Specify whether the Salt Master should store end times for jobs as returns
come in.

.. code-block:: yaml

text
job_cache_store_endtime: False

.. conf_master:: enforce_mine_cache

``enforce_mine_cache``

Default: False

By-default when disabling the minion_data_cache mine will stop working since
it is based on cached data, by enabling this option we explicitly enabling
only the cache for the mine system.

.. code-block:: yaml

text
enforce_mine_cache: False

.. conf_master:: max_minions

``max_minions``

Default: 0

The maximum number of minion connections allowed by the master. Use this to
accommodate the number of minions per master if you have different types of
hardware serving your minions. The default of 0 means unlimited connections.
Please note that this can slow down the authentication process a bit in large
setups.

.. code-block:: yaml

text
max_minions: 100

``con_cache``

Default: False

If max_minions is used in large installations, the master might experience
high-load situations because of having to check the number of connected
minions for every authentication. This cache provides the minion-ids of
all connected minions to all MWorker-processes and greatly improves the
performance of max_minions.

.. code-block:: yaml

text
con_cache: True

.. conf_master:: presence_events

``presence_events``

Default: False

Causes the master to periodically look for actively connected minions.
:ref:Presence events <event-master_presence> are fired on the event bus on a
regular interval with a list of connected minions, as well as events with lists
of newly connected or disconnected minions. This is a master-only operation
that does not send executions to minions.

.. code-block:: yaml

text
presence_events: False

``detect_remote_minions``

Default: False

When checking the minions connected to a master, also include the master's
connections to minions on the port specified in the setting remote_minions_port.
This is particularly useful when checking if the master is connected to any Heist-Salt
minions. If this setting is set to True, the master will check all connections on port 22
by default unless a user also configures a different port with the setting
remote_minions_port.

Changing this setting will check the remote minions the master is connected to when using
presence events, the manage runner, and any other parts of the code that call the
connected_ids method to check the status of connected minions.

.. code-block:: yaml

text
detect_remote_minions: True

``remote_minions_port``

Default: 22

The port to use when checking for remote minions when detect_remote_minions is set
to True.

.. code-block:: yaml

text
remote_minions_port: 2222

.. conf_master:: ping_on_rotate

``ping_on_rotate``

.. versionadded:: 2014.7.0

Default: False

By default, the master AES key rotates every 24 hours. The next command
following a key rotation will trigger a key refresh from the minion which may
result in minions which do not respond to the first command after a key refresh.

To tell the master to ping all minions immediately after an AES key refresh,
set ping_on_rotate to True. This should mitigate the issue where a
minion does not appear to initially respond after a key is rotated.

Note that enabling this may cause high load on the master immediately after the
key rotation event as minions reconnect. Consider this carefully if this salt
master is managing a large number of minions.

If disabled, it is recommended to handle this event by listening for the
aes_key_rotate event with the key tag and acting appropriately.

.. code-block:: yaml

text
ping_on_rotate: False

.. conf_master:: transport

``transport``

Default: zeromq

Changes the underlying transport layer. ZeroMQ is the recommended transport
while additional transport layers are under development. Supported values are
zeromq and tcp (experimental). This setting has a significant impact on
performance and should not be changed unless you know what you are doing!

.. code-block:: yaml

text
transport: zeromq

.. conf_master:: transport_opts

``transport_opts``

Default: {}

(experimental) Starts multiple transports and overrides options for each
transport with the provided dictionary This setting has a significant impact on
performance and should not be changed unless you know what you are doing! The
following example shows how to start a TCP transport alongside a ZMQ transport.

.. code-block:: yaml

text
transport_opts:
  tcp:
    publish_port: 4605
    ret_port: 4606
  zeromq: []

.. conf_master:: master_stats

``master_stats``

Default: False

Turning on the master stats enables runtime throughput and statistics events
to be fired from the master event bus. These events will report on what
functions have been run on the master and how long these runs have, on
average, taken over a given period of time.

.. conf_master:: master_stats_event_iter

``master_stats_event_iter``

Default: 60

The time in seconds to fire master_stats events. This will only fire in
conjunction with receiving a request to the master, idle masters will not
fire these events.

.. conf_master:: sock_pool_size

``sock_pool_size``

Default: 1

To avoid blocking waiting while writing a data to a socket, we support
socket pool for Salt applications. For example, a job with a large number
of target host list can cause long period blocking waiting. The option
is used by ZMQ and TCP transports, and the other transport methods don't
need the socket pool by definition. Most of Salt tools, including CLI,
are enough to use a single bucket of socket pool. On the other hands,
it is highly recommended to set the size of socket pool larger than 1
for other Salt applications, especially Salt API, which must write data
to socket concurrently.

.. code-block:: yaml

text
sock_pool_size: 15

.. conf_master:: ipc_mode

``ipc_mode``

Default: ipc

The ipc strategy. (i.e., sockets versus tcp, etc.) Windows platforms lack
POSIX IPC and must rely on TCP based inter-process communications. ipc_mode
is set to tcp by default on Windows.

.. code-block:: yaml

text
ipc_mode: ipc

.. conf_master:: ipc_write_buffer

``ipc_write_buffer``

Default: 0

The maximum size of a message sent via the IPC transport module can be limited
dynamically or by sharing an integer value lower than the total memory size. When
the value dynamic is set, salt will use 2.5% of the total memory as
ipc_write_buffer value (rounded to an integer). A value of 0 disables
this option.

.. code-block:: yaml

text
ipc_write_buffer: 10485760

.. conf_master:: tcp_master_pub_port

``tcp_master_pub_port``

Default: 4512

The TCP port on which events for the master should be published if ipc_mode is TCP.

.. code-block:: yaml

text
tcp_master_pub_port: 4512

.. conf_master:: tcp_master_pull_port

``tcp_master_pull_port``

Default: 4513

The TCP port on which events for the master should be pulled if ipc_mode is TCP.

.. code-block:: yaml

text
tcp_master_pull_port: 4513

.. conf_master:: tcp_master_publish_pull

``tcp_master_publish_pull``

Default: 4514

The TCP port on which events for the master should be pulled fom and then republished onto
the event bus on the master.

.. code-block:: yaml

text
tcp_master_publish_pull: 4514

.. conf_master:: tcp_master_workers

``tcp_master_workers``

Default: 4515

The TCP port for mworkers to connect to on the master.

.. code-block:: yaml

text
tcp_master_workers: 4515

.. conf_master:: auth_events

``auth_events``

.. versionadded:: 2017.7.3

Default: True

Determines whether the master will fire authentication events.
:ref:Authentication events <event-master_auth> are fired when
a minion performs an authentication check with the master.

.. code-block:: yaml

text
auth_events: True

.. conf_master:: minion_data_cache_events

``minion_data_cache_events``

.. versionadded:: 2017.7.3

Default: True

Determines whether the master will fire minion data cache events. Minion data
cache events are fired when a minion requests a minion data cache refresh.

.. code-block:: yaml

text
minion_data_cache_events: True

.. conf_master:: http_connect_timeout

``http_connect_timeout``

.. versionadded:: 2019.2.0

Default: 20

HTTP connection timeout in seconds.
Applied when fetching files using tornado back-end.
Should be greater than overall download time.

.. code-block:: yaml

text
http_connect_timeout: 20

.. conf_master:: http_request_timeout

``http_request_timeout``

.. versionadded:: 2015.8.0

Default: 3600

HTTP request timeout in seconds.
Applied when fetching files using tornado back-end.
Should be greater than overall download time.

.. code-block:: yaml

text
http_request_timeout: 3600

``use_yamlloader_old``

.. versionadded:: 2019.2.1

Default: False

Use the pre-2019.2 YAML renderer.
Uses legacy YAML rendering to support some legacy inline data structures.
See the :ref:2019.2.1 release notes <release-2019-2-1> for more details.

.. code-block:: yaml

text
use_yamlloader_old: False

.. conf_master:: req_server_niceness

``req_server_niceness``

.. versionadded:: 3001

Default: None

Process priority level of the ReqServer subprocess of the master.
Supported on POSIX platforms only.

.. code-block:: yaml

text
req_server_niceness: 9

.. conf_master:: pub_server_niceness

``pub_server_niceness``

.. versionadded:: 3001

Default: None

Process priority level of the PubServer subprocess of the master.
Supported on POSIX platforms only.

.. code-block:: yaml

text
pub_server_niceness: 9

.. conf_master:: fileserver_update_niceness

``fileserver_update_niceness``

.. versionadded:: 3001

Default: None

Process priority level of the FileServerUpdate subprocess of the master.
Supported on POSIX platforms only.

.. code-block:: yaml

text
fileserver_update_niceness: 9

.. conf_master:: maintenance_niceness

``maintenance_niceness``

.. versionadded:: 3001

Default: None

Process priority level of the Maintenance subprocess of the master.
Supported on POSIX platforms only.

.. code-block:: yaml

text
maintenance_niceness: 9

.. conf_master:: mworker_niceness

``mworker_niceness``

.. versionadded:: 3001

Default: None

Process priority level of the MWorker subprocess of the master.
Supported on POSIX platforms only.

.. code-block:: yaml

text
mworker_niceness: 9

.. conf_master:: mworker_queue_niceness

``mworker_queue_niceness``

.. versionadded:: 3001

default: None

process priority level of the MWorkerQueue subprocess of the master.
supported on POSIX platforms only.

.. code-block:: yaml

text
mworker_queue_niceness: 9

.. conf_master:: event_return_niceness

``event_return_niceness``

.. versionadded:: 3001

default: None

process priority level of the EventReturn subprocess of the master.
supported on POSIX platforms only.

.. code-block:: yaml

text
event_return_niceness: 9

.. conf_master:: event_publisher_niceness

``event_publisher_niceness``

.. versionadded:: 3001

default: none

process priority level of the EventPublisher subprocess of the master.
supported on POSIX platforms only.

.. code-block:: yaml

text
event_publisher_niceness: 9

.. conf_master:: reactor_niceness

``reactor_niceness``

.. versionadded:: 3001

default: None

process priority level of the Reactor subprocess of the master.
supported on POSIX platforms only.

.. code-block:: yaml

text
reactor_niceness: 9

.. _salt-ssh-configuration:

Salt-SSH Configuration

.. conf_master:: roster

``roster``

Default: flat

Define the default salt-ssh roster module to use

.. code-block:: yaml

text
roster: cache

.. conf_master:: roster_defaults

``roster_defaults``

.. versionadded:: 2017.7.0

Default settings which will be inherited by all rosters.

.. code-block:: yaml

text
roster_defaults:
  user: daniel
  sudo: True
  priv: /root/.ssh/id_rsa
  tty: True

.. conf_master:: roster_file

``roster_file``

Default: /etc/salt/roster

Pass in an alternative location for the salt-ssh :py:mod:flat <salt.roster.flat> roster file.

.. code-block:: yaml

text
roster_file: /root/roster

.. conf_master:: rosters

``rosters``

Default: None

Define locations for :py:mod:flat <salt.roster.flat> roster files so they can
be chosen when using Salt API. An administrator can place roster files into
these locations. Then, when calling Salt API, the :conf_master:roster_file
parameter should contain a relative path to these locations. That is,
roster_file=/foo/roster will be resolved as
/etc/salt/roster.d/foo/roster etc. This feature prevents passing insecure
custom rosters through the Salt API.

.. code-block:: yaml

text
rosters:
 - /etc/salt/roster.d
 - /opt/salt/some/more/rosters

.. conf_master:: ssh_passwd

``ssh_passwd``

Default: ''

The ssh password to log in with.

.. code-block:: yaml

text
ssh_passwd: ''

.. conf_master:: ssh_priv_passwd

``ssh_priv_passwd``

Default: ''

Passphrase for ssh private key file.

.. code-block:: yaml

text
ssh_priv_passwd: ''

.. conf_master:: ssh_port

``ssh_port``

Default: 22

The target system's ssh port number.

.. code-block:: yaml

text
ssh_port: 22

.. conf_master:: ssh_scan_ports

``ssh_scan_ports``

Default: 22

Comma-separated list of ports to scan.

.. code-block:: yaml

text
ssh_scan_ports: 22

.. conf_master:: ssh_scan_timeout

``ssh_scan_timeout``

Default: 0.01

Scanning socket timeout for salt-ssh.

.. code-block:: yaml

text
ssh_scan_timeout: 0.01

.. conf_master:: ssh_sudo

``ssh_sudo``

Default: False

Boolean to run command via sudo.

.. code-block:: yaml

text
ssh_sudo: False

.. conf_master:: ssh_timeout

``ssh_timeout``

Default: 60

Number of seconds to wait for a response when establishing an SSH connection.

.. code-block:: yaml

text
ssh_timeout: 60

.. conf_master:: ssh_user

``ssh_user``

Default: root

The user to log in as.

.. code-block:: yaml

text
ssh_user: root

.. conf_master:: ssh_log_file

``ssh_log_file``

.. versionadded:: 2016.3.5

Default: /var/log/salt/ssh

Specify the log file of the salt-ssh command.

.. code-block:: yaml

text
ssh_log_file: /var/log/salt/ssh

.. conf_master:: ssh_minion_opts

``ssh_minion_opts``

Default: None

Pass in minion option overrides that will be inserted into the SHIM for
salt-ssh calls. The local minion config is not used for salt-ssh. Can be
overridden on a per-minion basis in the roster (minion_opts)

.. code-block:: yaml

text
ssh_minion_opts:
  gpg_keydir: /root/gpg

.. conf_master:: ssh_use_home_key

``ssh_use_home_key``

Default: False

Set this to True to default to using ~/.ssh/id_rsa for salt-ssh
authentication with minions

.. code-block:: yaml

text
ssh_use_home_key: False

.. conf_master:: ssh_identities_only

``ssh_identities_only``

Default: False

Set this to True to default salt-ssh to run with -o IdentitiesOnly=yes. This
option is intended for situations where the ssh-agent offers many different identities
and allows ssh to ignore those identities and use the only one specified in options.

.. code-block:: yaml

text
ssh_identities_only: False

.. conf_master:: ssh_list_nodegroups

``ssh_list_nodegroups``

Default: {}

List-only nodegroups for salt-ssh. Each group must be formed as either a comma-separated
list, or a YAML list. This option is useful to group minions into easy-to-target groups
when using salt-ssh. These groups can then be targeted with the normal -N argument to
salt-ssh.

.. code-block:: yaml

text
ssh_list_nodegroups:
  groupA: minion1,minion2
  groupB: minion1,minion3

.. conf_master:: ssh_run_pre_flight

Default: False

Run the ssh_pre_flight script defined in the salt-ssh roster. By default
the script will only run when the thin dir does not exist on the targeted
minion. This will force the script to run and not check if the thin dir
exists first.

.. conf_master:: thin_extra_mods

``thin_extra_mods``

Default: None

List of additional modules, needed to be included into the Salt Thin.
Pass a list of importable Python modules that are typically located in
the site-packages Python directory so they will be also always included
into the Salt Thin, once generated.

``min_extra_mods``

Default: None

Identical as thin_extra_mods, only applied to the Salt Minimal.

.. _master-security-settings:

Master Security Settings

.. conf_master:: open_mode

``open_mode``

Default: False

Open mode is a dangerous security feature. One problem encountered with pki
authentication systems is that keys can become "mixed up" and authentication
begins to fail. Open mode turns off authentication and tells the master to
accept all authentication. This will clean up the pki keys received from the
minions. Open mode should not be turned on for general use. Open mode should
only be used for a short period of time to clean up pki keys. To turn on open
mode set this value to True.

.. code-block:: yaml

text
open_mode: False

.. conf_master:: auto_accept

``auto_accept``

Default: False

Enable auto_accept. This setting will automatically accept all incoming
public keys from minions.

.. code-block:: yaml

text
auto_accept: False

.. conf_master:: keysize

``keysize``

Default: 2048

The size of key that should be generated when creating new keys.

.. code-block:: yaml

text
keysize: 2048

.. conf_master:: autosign_timeout

``autosign_timeout``

.. versionadded:: 2014.7.0

Default: 120

Time in minutes that a incoming public key with a matching name found in
pki_dir/minion_autosign/keyid is automatically accepted. Expired autosign keys
are removed when the master checks the minion_autosign directory. This method
to auto accept minions can be safer than an autosign_file because the
keyid record can expire and is limited to being an exact name match.
This should still be considered a less than secure option, due to the fact
that trust is based on just the requesting minion id.

.. conf_master:: autosign_file

``autosign_file``

Default: not defined

If the autosign_file is specified incoming keys specified in the autosign_file
will be automatically accepted. Matches will be searched for first by string
comparison, then by globbing, then by full-string regex matching.
This should still be considered a less than secure option, due to the fact
that trust is based on just the requesting minion id.

.. versionchanged:: 2018.3.0
For security reasons the file must be readonly except for its owner.
If :conf_master:permissive_pki_access is True the owning group can also
have write access, but if Salt is running as root it must be a member of that group.
A less strict requirement also existed in previous version.

.. conf_master:: autoreject_file

``autoreject_file``

.. versionadded:: 2014.1.0

Default: not defined

Works like :conf_master:autosign_file, but instead allows you to specify
minion IDs for which keys will automatically be rejected. Will override both
membership in the :conf_master:autosign_file and the
:conf_master:auto_accept setting.

.. conf_master:: autosign_grains_dir

``autosign_grains_dir``

.. versionadded:: 2018.3.0

Default: not defined

If the autosign_grains_dir is specified, incoming keys from minions with
grain values that match those defined in files in the autosign_grains_dir
will be accepted automatically. Grain values that should be accepted automatically
can be defined by creating a file named like the corresponding grain in the
autosign_grains_dir and writing the values into that file, one value per line.
Lines starting with a # will be ignored.
Minion must be configured to send the corresponding grains on authentication.
This should still be considered a less than secure option, due to the fact
that trust is based on just the requesting minion.

Please see the :ref:Autoaccept Minions from Grains <tutorial-autoaccept-grains>
documentation for more information.

.. code-block:: yaml

text
autosign_grains_dir: /etc/salt/autosign_grains

.. conf_master:: permissive_pki_access

``permissive_pki_access``

Default: False

Enable permissive access to the salt keys. This allows you to run the
master or minion as root, but have a non-root group be given access to
your pki_dir. To make the access explicit, root must belong to the group
you've given access to. This is potentially quite insecure. If an autosign_file
is specified, enabling permissive_pki_access will allow group access to that
specific file.

.. code-block:: yaml

text
permissive_pki_access: False

.. conf_master:: publisher_acl

``publisher_acl``

Default: {}

Enable user accounts on the master to execute specific modules. These modules
can be expressed as regular expressions.

.. code-block:: yaml

text
publisher_acl:
  fred:
    - test.ping
    - pkg.*

.. conf_master:: publisher_acl_blacklist

``publisher_acl_blacklist``

Default: {}

Blacklist users or modules

This example would blacklist all non sudo users, including root from
running any commands. It would also blacklist any use of the "cmd"
module.

This is completely disabled by default.

.. code-block:: yaml

text
publisher_acl_blacklist:
  users:
    - root
    - '^(?!sudo_).*$'   #  all non sudo users
  modules:
    - cmd.*
    - test.echo

.. conf_master:: sudo_acl

``sudo_acl``

Default: False

Enforce publisher_acl and publisher_acl_blacklist when users have sudo
access to the salt command.

.. code-block:: yaml

text
sudo_acl: False

.. conf_master:: external_auth

``external_auth``

Default: {}

The external auth system uses the Salt auth modules to authenticate and
validate users to access areas of the Salt system.

.. code-block:: yaml

text
external_auth:
  pam:
    fred:
      - test.*

.. conf_master:: token_expire

``token_expire``

Default: 43200

Time (in seconds) for a newly generated token to live.

Default: 12 hours

.. code-block:: yaml

text
token_expire: 43200

.. conf_master:: token_expire_user_override

``token_expire_user_override``

Default: False

Allow eauth users to specify the expiry time of the tokens they generate.

A boolean applies to all users or a dictionary of whitelisted eauth backends
and usernames may be given:

.. code-block:: yaml

text
token_expire_user_override:
  pam:
    - fred
    - tom
  ldap:
    - gary

.. conf_master:: keep_acl_in_token

``keep_acl_in_token``

Default: False

Set to True to enable keeping the calculated user's auth list in the token
file. This is disabled by default and the auth list is calculated or requested
from the eauth driver each time.

Note: keep_acl_in_token will be forced to True when using external authentication
for REST API (rest is present under external_auth). This is because the REST API
does not store the password, and can therefore not retroactively fetch the ACL, so
the ACL must be stored in the token.

.. code-block:: yaml

text
keep_acl_in_token: False

.. conf_master:: eauth_acl_module

``eauth_acl_module``

Default: ''

Auth subsystem module to use to get authorized access list for a user. By default it's
the same module used for external authentication.

.. code-block:: yaml

text
eauth_acl_module: django

.. conf_master:: file_recv

``file_recv``

Default: False

Allow minions to push files to the master. This is disabled by default, for
security purposes.

.. code-block:: yaml

text
file_recv: False

.. conf_master:: file_recv_max_size

``file_recv_max_size``

.. versionadded:: 2014.7.0

Default: 100

Set a hard-limit on the size of the files that can be pushed to the master.
It will be interpreted as megabytes.

.. code-block:: yaml

text
file_recv_max_size: 100

.. conf_master:: master_sign_pubkey

``master_sign_pubkey``

Default: False

Sign the master auth-replies with a cryptographic signature of the master's
public key. Please see the tutorial how to use these settings in the
Multimaster-PKI with Failover Tutorial <https://docs.saltproject.io/en/latest/topics/tutorials/multimaster_pki.html>_

.. code-block:: yaml

text
master_sign_pubkey: True

.. conf_master:: master_sign_key_name

``master_sign_key_name``

Default: master_sign

The customizable name of the signing-key-pair without suffix.

.. code-block:: yaml

text
master_sign_key_name: <filename_without_suffix>

.. conf_master:: master_pubkey_signature

``master_pubkey_signature``

Default: master_pubkey_signature

The name of the file in the master's pki-directory that holds the pre-calculated
signature of the master's public-key.

.. code-block:: yaml

text
master_pubkey_signature: <filename>

.. conf_master:: master_use_pubkey_signature

``master_use_pubkey_signature``

Default: False

Instead of computing the signature for each auth-reply, use a pre-calculated
signature. The :conf_master:master_pubkey_signature must also be set for this.

.. code-block:: yaml

text
master_use_pubkey_signature: True

.. conf_master:: rotate_aes_key

``rotate_aes_key``

Default: True

Rotate the salt-masters AES-key when a minion-public is deleted with salt-key.
This is a very important security-setting. Disabling it will enable deleted
minions to still listen in on the messages published by the salt-master.
Do not disable this unless it is absolutely clear what this does.

.. code-block:: yaml

text
rotate_aes_key: True

.. conf_master:: publish_session

``publish_session``

Default: 86400

The number of seconds between AES key rotations on the master.

.. code-block:: yaml

text
publish_session: Default: 86400

.. conf_master:: ssl

``publish_signing_algorithm``

.. versionadded:: 3006.9

Default: PKCS1v15-SHA1

The RSA signing algorithm used by this minion when connecting to the
master's request channel. Valid values are PKCS1v15-SHA1 and
PKCS1v15-SHA224. Minions must be at version 3006.9 or greater if this
is changed from the default setting.

.. conf_master:: minimum_auth_version

``minimum_auth_version``

.. versionadded:: 3006.17,3007.9

Default: 3

Enforce a minimum authentication protocol version from minions connecting to the master.
This setting protects against authentication downgrade attacks (CVE-2025-62349) where a
malicious minion attempts to use an older, less secure authentication protocol version to
bypass security features introduced in newer protocol versions.

Authentication protocol versions and their security features:

  • Version 0/1: No message signing, no nonce, no security features (legacy, insecure)
  • Version 2: Message signing and nonce, but missing TTL validation, token validation,
    and minion ID matching (partially secure)
  • Version 3+: Full security with message signing, nonce, TTL checks, token validation,
    minion ID matching, and session keys (default and recommended)

Security-by-Default:

The default value of 3 enforces modern authentication protocol for maximum security.
New installations automatically receive protection against authentication downgrade attacks
without requiring additional configuration.

Important for Upgrades:

If you are upgrading a Salt deployment with minions running older versions that do not
support authentication protocol version 3, you must temporarily lower this value during
the upgrade process to prevent minions from being locked out.

Upgrade Path for Environments with Older Minions:

  1. Before upgrading your Salt Master, set minimum_auth_version: 0 in master config
  2. Upgrade your Salt Master to a version supporting minimum_auth_version
  3. Restart the Salt Master
  4. Upgrade all minions to a version supporting authentication protocol v3+
  5. Remove the minimum_auth_version: 0 override (or explicitly set to 3)
  6. Restart the Salt Master to enforce the secure default

.. code-block:: yaml

text
# Default - enforces modern authentication protocol (secure)
minimum_auth_version: 3

# Temporary setting for upgrades with older minions
minimum_auth_version: 0

.. warning::
Setting minimum_auth_version to a value higher than what your minions support
will prevent those minions from authenticating. Ensure all minions are upgraded
before increasing this value. Check your minion versions before changing this setting.

.. note::
When a minion's authentication is rejected due to insufficient protocol version,
a warning message will be logged on the master including the minion ID and the
protocol version it attempted to use.

``ssl``

.. versionadded:: 2016.11.0

Default: None

TLS/SSL connection options. This could be set to a dictionary containing
arguments corresponding to python ssl.wrap_socket method. For details see
Tornado <http://www.tornadoweb.org/en/stable/tcpserver.html#tornado.tcpserver.TCPServer>_
and Python <https://docs.python.org/3/library/ssl.html#ssl.wrap_socket>_
documentation.

Note: to set enum arguments values like cert_reqs and ssl_version use
constant names without ssl module prefix: CERT_REQUIRED or PROTOCOL_SSLv23.

.. code-block:: yaml

text
ssl:
    keyfile: 
    certfile: 
    ssl_version: PROTOCOL_TLSv1_2

.. conf_master:: preserve_minion_cache

``preserve_minion_cache``

Default: False

By default, the master deletes its cache of minion data when the key for that
minion is removed. To preserve the cache after key deletion, set
preserve_minion_cache to True.

WARNING: This may have security implications if compromised minions auth with
a previous deleted minion ID.

.. code-block:: yaml

text
preserve_minion_cache: False

.. conf_master:: allow_minion_key_revoke

``allow_minion_key_revoke``

Default: True

Controls whether a minion can request its own key revocation. When True
the master will honor the minion's request and revoke its key. When False,
the master will drop the request and the minion's key will remain accepted.

.. code-block:: yaml

text
allow_minion_key_revoke: False

.. conf_master:: optimization_order

``optimization_order``

Default: [0, 1, 2]

In cases where Salt is distributed without .py files, this option determines
the priority of optimization level(s) Salt's module loader should prefer.

.. note::
This option is only supported on Python 3.5+.

.. code-block:: yaml

text
optimization_order:
  - 2
  - 0
  - 1

Master Large Scale Tuning Settings

.. conf_master:: max_open_files

``max_open_files``

Default: 100000

Each minion connecting to the master uses AT LEAST one file descriptor, the
master subscription connection. If enough minions connect you might start
seeing on the console(and then salt-master crashes):

.. code-block:: text

text
Too many open files (tcp_listener.cpp:335)
Aborted (core dumped)

.. code-block:: yaml

text
max_open_files: 100000

By default this value will be the one of ulimit -Hn, i.e., the hard limit for
max open files.

To set a different value than the default one, uncomment, and configure this
setting. Remember that this value CANNOT be higher than the hard limit. Raising
the hard limit depends on the OS and/or distribution, a good way to find the
limit is to search the internet for something like this:

.. code-block:: text

text
raise max open files hard limit debian

.. conf_master:: worker_threads

``worker_threads``

Default: 5

The number of threads to start for receiving commands and replies from minions.
If minions are stalling on replies because you have many minions, raise the
worker_threads value.

Worker threads should not be put below 3 when using the peer system, but can
drop down to 1 worker otherwise.

Standards for busy environments:

  • Use one worker thread per 200 minions.
  • The value of worker_threads should not exceed 1½ times the available CPU cores.

.. note::
When the master daemon starts, it is expected behaviour to see
multiple salt-master processes, even if 'worker_threads' is set to '1'. At
a minimum, a controlling process will start along with a Publisher, an
EventPublisher, and a number of MWorker processes will be started. The
number of MWorker processes is tuneable by the 'worker_threads'
configuration value while the others are not.

.. code-block:: yaml

text
worker_threads: 5

.. conf_master:: pub_hwm

``pub_hwm``

Default: 1000

The zeromq high water mark on the publisher interface.

.. code-block:: yaml

text
pub_hwm: 1000

.. conf_master:: zmq_backlog

``zmq_backlog``

Default: 1000

The listen queue size of the ZeroMQ backlog.

.. code-block:: yaml

text
zmq_backlog: 1000

.. _master-module-management:

Master Module Management

.. conf_master:: runner_dirs

``runner_dirs``

Default: []

Set additional directories to search for runner modules.

.. code-block:: yaml

text
runner_dirs:
  - /var/lib/salt/runners

.. conf_master:: utils_dirs

``utils_dirs``

.. versionadded:: 2018.3.0

Default: []

Set additional directories to search for util modules.

.. code-block:: yaml

text
utils_dirs:
  - /var/lib/salt/utils

.. conf_master:: cython_enable

``cython_enable``

Default: False

Set to true to enable Cython modules (.pyx files) to be compiled on the fly on
the Salt master.

.. code-block:: yaml

text
cython_enable: False

.. _master-state-system-settings:

Master State System Settings

.. conf_master:: state_top

``state_top``

Default: top.sls

The state system uses a "top" file to tell the minions what environment to
use and what modules to use. The state_top file is defined relative to the
root of the base environment. The value of "state_top" is also used for the
pillar top file

.. code-block:: yaml

text
state_top: top.sls

.. conf_master:: state_top_saltenv

``state_top_saltenv``

This option has no default value. Set it to an environment name to ensure that
only the top file from that environment is considered during a
:ref:highstate <running-highstate>.

.. note::
Using this value does not change the merging strategy. For instance, if
:conf_master:top_file_merging_strategy is set to merge, and
:conf_master:state_top_saltenv is set to foo, then any sections for
environments other than foo in the top file for the foo environment
will be ignored. With :conf_master:state_top_saltenv set to base, all
states from all environments in the base top file will be applied,
while all other top files are ignored. The only way to set
:conf_master:state_top_saltenv to something other than base and not
have the other environments in the targeted top file ignored, would be to
set :conf_master:top_file_merging_strategy to merge_all.

.. code-block:: yaml

text
state_top_saltenv: dev

.. conf_master:: top_file_merging_strategy

``top_file_merging_strategy``

.. versionchanged:: 2016.11.0
A merge_all strategy has been added.

Default: merge

When no specific fileserver environment (a.k.a. saltenv) has been specified
for a :ref:highstate <running-highstate>, all environments' top files are
inspected. This config option determines how the SLS targets in those top files
are handled.

When set to merge, the base environment's top file is evaluated first,
followed by the other environments' top files. The first target expression
(e.g. '*') for a given environment is kept, and when the same target
expression is used in a different top file evaluated later, it is ignored.
Because base is evaluated first, it is authoritative. For example, if there
is a target for '*' for the foo environment in both the base and
foo environment's top files, the one in the foo environment would be
ignored. The environments will be evaluated in no specific order (aside from
base coming first). For greater control over the order in which the
environments are evaluated, use :conf_master:env_order. Note that, aside from
the base environment's top file, any sections in top files that do not
match that top file's environment will be ignored. So, for example, a section
for the qa environment would be ignored if it appears in the dev
environment's top file. To keep use cases like this from being ignored, use the
merge_all strategy.

When set to same, then for each environment, only that environment's top
file is processed, with the others being ignored. For example, only the dev
environment's top file will be processed for the dev environment, and any
SLS targets defined for dev in the base environment's (or any other
environment's) top file will be ignored. If an environment does not have a top
file, then the top file from the :conf_master:default_top config parameter
will be used as a fallback.

When set to merge_all, then all states in all environments in all top files
will be applied. The order in which individual SLS files will be executed will
depend on the order in which the top files were evaluated, and the environments
will be evaluated in no specific order. For greater control over the order in
which the environments are evaluated, use :conf_master:env_order.

.. code-block:: yaml

text
top_file_merging_strategy: same

.. conf_master:: env_order

``env_order``

Default: []

When :conf_master:top_file_merging_strategy is set to merge, and no
environment is specified for a :ref:highstate <running-highstate>, this
config option allows for the order in which top files are evaluated to be
explicitly defined.

.. code-block:: yaml

text
env_order:
  - base
  - dev
  - qa

.. conf_master:: master_tops

``master_tops``

Default: {}

The master_tops option replaces the external_nodes option by creating
a pluggable system for the generation of external top data. The external_nodes
option is deprecated by the master_tops option.
To gain the capabilities of the classic external_nodes system, use the
following configuration:

.. code-block:: yaml

text
master_tops:
  ext_nodes: <Shell command which returns yaml>

.. conf_master:: renderer

``renderer``

Default: jinja|yaml

The renderer to use on the minions to render the state data.

.. code-block:: yaml

text
renderer: jinja|json

.. conf_master:: userdata_template

``userdata_template``

.. versionadded:: 2016.11.4

Default: None

The renderer to use for templating userdata files in salt-cloud, if the
userdata_template is not set in the cloud profile. If no value is set in
the cloud profile or master config file, no templating will be performed.

.. code-block:: yaml

text
userdata_template: jinja

.. conf_master:: jinja_env

``jinja_env``

.. versionadded:: 2018.3.0

Default: {}

jinja_env overrides the default Jinja environment options for
all templates except sls templates.
To set the options for sls templates use :conf_master:jinja_sls_env.

.. note::

text
The `Jinja2 Environment documentation <https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Environment>`_ is the official source for the default values.
Not all the options listed in the jinja documentation can be overridden using :conf_master:`jinja_env` or :conf_master:`jinja_sls_env`.

.. note::

text
:conf_master:`jinja_env` and :conf_master:`jinja_sls_env` apply to **every**
template, so changing them can break unrelated states or third-party
formulas that were written for the defaults. To set Jinja environment
options for a single template instead, add a ``#jinja2:`` header to that
template (see :ref:`Jinja Environment Configuration Override <jinja-fileopts>`).

The default options are:

.. code-block:: yaml

text
jinja_env:
  block_start_string: '{%'
  block_end_string: '%}'
  variable_start_string: '{{'
  variable_end_string: '}}'
  comment_start_string: '{#'
  comment_end_string: '#}'
  line_statement_prefix:
  line_comment_prefix:
  trim_blocks: False
  lstrip_blocks: False
  newline_sequence: '\n'
  keep_trailing_newline: False

.. conf_master:: jinja_sls_env

``jinja_sls_env``

.. versionadded:: 2018.3.0

Default: {}

jinja_sls_env sets the Jinja environment options for sls templates.
The defaults and accepted options are exactly the same as they are
for :conf_master:jinja_env.

The default options are:

.. code-block:: yaml

text
jinja_sls_env:
  block_start_string: '{%'
  block_end_string: '%}'
  variable_start_string: '{{'
  variable_end_string: '}}'
  comment_start_string: '{#'
  comment_end_string: '#}'
  line_statement_prefix:
  line_comment_prefix:
  trim_blocks: False
  lstrip_blocks: False
  newline_sequence: '\n'
  keep_trailing_newline: False

Example using line statements and line comments to increase ease of use:

If your configuration options are

.. code-block:: yaml

text
jinja_sls_env:
  line_statement_prefix: '%'
  line_comment_prefix: '##'

With these options jinja will interpret anything after a % at the start of a line (ignoreing whitespace)
as a jinja statement and will interpret anything after a ## as a comment.

This allows the following more convenient syntax to be used:

.. code-block:: jinja

text
## (this comment will not stay once rendered)
# (this comment remains in the rendered template)
## ensure all the formula services are running
% for service in formula_services:
enable_service_{{ service }}:
  service.running:
    name: {{ service }}
% endfor

The following less convenient but equivalent syntax would have to
be used if you had not set the line_statement and line_comment options:

.. code-block:: jinja

text
{# (this comment will not stay once rendered) #}
# (this comment remains in the rendered template)
{# ensure all the formula services are running #}
{% for service in formula_services %}
enable_service_{{ service }}:
  service.running:
    name: {{ service }}
{% endfor %}

.. conf_master:: jinja_trim_blocks

``jinja_trim_blocks``

.. deprecated:: 2018.3.0
Replaced by :conf_master:jinja_env and :conf_master:jinja_sls_env

.. versionadded:: 2014.1.0

Default: False

If this is set to True, the first newline after a Jinja block is
removed (block, not variable tag!). Defaults to False and corresponds
to the Jinja environment init variable trim_blocks.

.. code-block:: yaml

text
jinja_trim_blocks: False

.. conf_master:: jinja_lstrip_blocks

``jinja_lstrip_blocks``

.. deprecated:: 2018.3.0
Replaced by :conf_master:jinja_env and :conf_master:jinja_sls_env

.. versionadded:: 2014.1.0

Default: False

If this is set to True, leading spaces and tabs are stripped from the
start of a line to a block. Defaults to False and corresponds to the
Jinja environment init variable lstrip_blocks.

.. code-block:: yaml

text
jinja_lstrip_blocks: False

.. conf_master:: failhard

``failhard``

Default: False

Set the global failhard flag. This informs all states to stop running states
at the moment a single state fails.

.. code-block:: yaml

text
failhard: False

.. conf_master:: state_verbose

``state_verbose``

Default: True

Controls the verbosity of state runs. By default, the results of all states are
returned, but setting this value to False will cause salt to only display
output for states that failed or states that have changes.

.. code-block:: yaml

text
state_verbose: False

.. conf_master:: state_output

``state_output``

Default: full

The state_output setting controls which results will be output full multi line:

  • full, terse - each state will be full/terse
  • mixed - only states with errors will be full
  • changes - states with changes and errors will be full

full_id, mixed_id, changes_id and terse_id are also allowed;
when set, the state ID will be used as name in the output.

Any of the above modes can be suffixed with _color (e.g. full_color,
mixed_color) to enable colorized unified diff output in the changes
section. Added lines are shown in green, removed lines in red, hunk headers
in cyan, and context lines in gray. All other output behavior is identical to
the mode without the _color suffix.

.. code-block:: yaml

text
state_output: full

.. code-block:: yaml

text
state_output: full_color

.. conf_master:: state_output_diff

``state_output_diff``

Default: False

The state_output_diff setting changes whether or not the output from
successful states is returned. Useful when even the terse output of these
states is cluttering the logs. Set it to True to ignore them.

.. code-block:: yaml

text
state_output_diff: False

.. conf_master:: state_output_profile

``state_output_profile``

Default: True

The state_output_profile setting changes whether profile information
will be shown for each state run.

.. code-block:: yaml

text
state_output_profile: True

.. conf_master:: state_output_pct

``state_output_pct``

Default: False

The state_output_pct setting changes whether success and failure information
as a percent of total actions will be shown for each state run.

.. code-block:: yaml

text
state_output_pct: False

.. conf_master:: state_compress_ids

``state_compress_ids``

Default: False

The state_compress_ids setting aggregates information about states which
have multiple "names" under the same state ID in the highstate output.

.. code-block:: yaml

text
state_compress_ids: False

.. conf_master:: state_aggregate

``state_aggregate``

Default: False

Automatically aggregate all states that have support for mod_aggregate by
setting to True.

.. code-block:: yaml

text
state_aggregate: True

Or pass a list of state module names to automatically
aggregate just those types.

.. code-block:: yaml

text
state_aggregate:
  - pkg

.. conf_master:: state_events

``state_events``

Default: False

Send progress events as each function in a state run completes execution
by setting to True. Progress events are in the format
salt/job/<JID>/prog/<MID>/<RUN NUM>.

.. code-block:: yaml

text
state_events: True

.. conf_master:: yaml_utf8

``yaml_utf8``

Default: False

Enable extra routines for YAML renderer used states containing UTF characters.

.. code-block:: yaml

text
yaml_utf8: False

``runner_returns``

Default: True

If set to False, runner jobs will not be saved to job cache (defined by
:conf_master:master_job_cache).

.. code-block:: yaml

text
runner_returns: False

.. _master-file-server-settings:

Master File Server Settings

.. conf_master:: fileserver_backend

``fileserver_backend``

Default: ['roots']

Salt supports a modular fileserver backend system, this system allows the salt
master to link directly to third party systems to gather and manage the files
available to minions. Multiple backends can be configured and will be searched
for the requested file in the order in which they are defined here. The default
setting only enables the standard backend roots, which is configured using
the :conf_master:file_roots option.

Example:

.. code-block:: yaml

text
fileserver_backend:
  - roots
  - gitfs

.. note::
For masterless Salt, this parameter must be specified in the minion config
file.

.. conf_master:: fileserver_followsymlinks

.. versionadded:: 2014.1.0

Default: True

By default, the file_server follows symlinks when walking the filesystem tree.
Currently this only applies to the default roots fileserver_backend.

.. code-block:: yaml

text
fileserver_followsymlinks: True

.. conf_master:: fileserver_ignoresymlinks

.. versionadded:: 2014.1.0

Default: False

If you do not want symlinks to be treated as the files they are pointing to,
set fileserver_ignoresymlinks to True. By default this is set to
False. When set to True, any detected symlink while listing files on the
Master will not be returned to the Minion.

.. code-block:: yaml

text
fileserver_ignoresymlinks: False

.. conf_master:: fileserver_list_cache_time

``fileserver_list_cache_time``

.. versionadded:: 2014.1.0
.. versionchanged:: 2016.11.0
The default was changed from 30 seconds to 20.

Default: 20

Salt caches the list of files/symlinks/directories for each fileserver backend
and environment as they are requested, to guard against a performance
bottleneck at scale when many minions all ask the fileserver which files are
available simultaneously. This configuration parameter allows for the max age
of that cache to be altered.

Set this value to 0 to disable use of this cache altogether, but keep in
mind that this may increase the CPU load on the master when running a highstate
on a large number of minions.

.. note::
Rather than altering this configuration parameter, it may be advisable to
use the :mod:fileserver.clear_file_list_cache <salt.runners.fileserver.clear_file_list_cache> runner to clear these
caches.

.. code-block:: yaml

text
fileserver_list_cache_time: 5

.. conf_master:: fileserver_verify_config

``fileserver_verify_config``

.. versionadded:: 2017.7.0

Default: True

By default, as the master starts it performs some sanity checks on the
configured fileserver backends. If any of these sanity checks fail (such as
when an invalid configuration is used), the master daemon will abort.

To skip these sanity checks, set this option to False.

.. code-block:: yaml

text
fileserver_verify_config: False

.. conf_master:: hash_type

``hash_type``

Default: sha256

The hash_type is the hash to use when discovering the hash of a file on
the master server. The default is sha256, but md5, sha1, sha224, sha384, and
sha512 are also supported.

.. code-block:: yaml

text
hash_type: sha256

.. conf_master:: file_buffer_size

``file_buffer_size``

Default: 1048576

The buffer size in the file server in bytes.

.. code-block:: yaml

text
file_buffer_size: 1048576

.. conf_master:: file_ignore_regex

``file_ignore_regex``

Default: ''

A regular expression (or a list of expressions) that will be matched
against the file path before syncing the modules and states to the minions.
This includes files affected by the file.recurse state.
For example, if you manage your custom modules and states in subversion
and don't want all the '.svn' folders and content synced to your minions,
you could set this to '/.svn($|/)'. By default nothing is ignored.

.. code-block:: yaml

text
file_ignore_regex:
  - '/\.svn($|/)'
  - '/\.git($|/)'

.. conf_master:: file_ignore_glob

``file_ignore_glob``

Default ''

A file glob (or list of file globs) that will be matched against the file
path before syncing the modules and states to the minions. This is similar
to file_ignore_regex above, but works on globs instead of regex. By default
nothing is ignored.

.. code-block:: yaml

text
file_ignore_glob:
  - '\*.pyc'
  - '\*/somefolder/\*.bak'
  - '\*.swp'

.. note::
Vim's .swp files are a common cause of Unicode errors in
:py:func:file.recurse <salt.states.file.recurse> states which use
templating. Unless there is a good reason to distribute them via the
fileserver, it is good practice to include '\*.swp' in the
:conf_master:file_ignore_glob.

.. conf_master:: master_roots

``master_roots``

Default: ''

A master-only copy of the :conf_master:file_roots dictionary, used by the
state compiler.

Example:

.. code-block:: yaml

text
master_roots:
  base:
    - /srv/salt-master

roots: Master's Local File Server

.. conf_master:: file_roots

file_roots


.. versionchanged:: 3005

Default:

.. code-block:: yaml

text
base:
  - /srv/salt

Salt runs a lightweight file server written in ZeroMQ to deliver files to
minions. This file server is built into the master daemon and does not
require a dedicated port.

The file server works on environments passed to the master. Each environment
can have multiple root directories. The subdirectories in the multiple file
roots cannot match, otherwise the downloaded files will not be able to be
reliably ensured. A base environment is required to house the top file.

As of 2018.3.5 and 2019.2.1, it is possible to have __env__ as a catch-all environment.

Example:

.. code-block:: yaml

text
file_roots:
  base:
    - /srv/salt
  dev:
    - /srv/salt/dev/services
    - /srv/salt/dev/states
  prod:
    - /srv/salt/prod/services
    - /srv/salt/prod/states
  __env__:
    - /srv/salt/default

Taking dynamic environments one step further, __env__ can also be used in
the file_roots filesystem path as of version 3005. It will be replaced with
the actual saltenv and searched for states and data to provide to the
minion. Note this substitution ONLY occurs for the __env__ environment. For
instance, this configuration:

.. code-block:: yaml

text
file_roots:
  __env__:
    - /srv/__env__/salt

is equivalent to this static configuration:

.. code-block:: yaml

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

.. note::
For masterless Salt, this parameter must be specified in the minion config
file.

.. conf_master:: roots_update_interval

roots_update_interval


.. versionadded:: 2018.3.0

Default: 60

This option defines the update interval (in seconds) for
:conf_master:file_roots.

.. note::
Since file_roots consists of files local to the minion, the update
process for this fileserver backend just reaps the cache for this backend.

.. code-block:: yaml

text
roots_update_interval: 120

gitfs: Git Remote File Server Backend

.. conf_master:: gitfs_remotes

gitfs_remotes


Default: []

When using the git fileserver backend at least one git remote needs to be
defined. The user running the salt master will need read access to the repo.

The repos will be searched in order to find the file requested by a client and
the first repo to have the file will return it. Branches and tags are
translated into salt environments.

.. code-block:: yaml

text
gitfs_remotes:
  - git://github.com/saltstack/salt-states.git
  - file:///var/git/saltmaster

.. note::

text
``file://`` repos will be treated as a remote and copied into the master's
gitfs cache, so only the *local* refs for those repos will be exposed as
fileserver environments.

As of 2014.7.0, it is possible to have per-repo versions of several of the
gitfs configuration parameters. For more information, see the :ref:GitFS Walkthrough <gitfs-per-remote-config>.

.. conf_master:: gitfs_provider

gitfs_provider


.. versionadded:: 2014.7.0

Optional parameter used to specify the provider to be used for gitfs. More
information can be found in the :ref:GitFS Walkthrough <gitfs-dependencies>.

Must be either pygit2 or gitpython. If unset, then each will be tried
in that same order, and the first one with a compatible version installed will
be the provider that is used.

.. code-block:: yaml

text
gitfs_provider: gitpython

.. conf_master:: gitfs_ssl_verify

gitfs_ssl_verify


Default: True

Specifies whether or not to ignore SSL certificate errors when fetching from
the repositories configured in :conf_master:gitfs_remotes. The False
setting is useful if you're using a git repo that uses a self-signed
certificate. However, keep in mind that setting this to anything other True
is a considered insecure, and using an SSH-based transport (if available) may
be a better option.

.. code-block:: yaml

text
gitfs_ssl_verify: False

.. note::
pygit2 only supports disabling SSL verification in versions 0.23.2 and
newer.

.. versionchanged:: 2015.8.0
This option can now be configured on individual repositories as well. See
:ref:here <gitfs-per-remote-config> for more info.

.. versionchanged:: 2016.11.0
The default config value changed from False to True.

.. conf_master:: gitfs_mountpoint

gitfs_mountpoint


.. versionadded:: 2014.7.0

Default: ''

Specifies a path on the salt fileserver which will be prepended to all files
served by gitfs. This option can be used in conjunction with
:conf_master:gitfs_root. It can also be configured for an individual
repository, see :ref:here <gitfs-per-remote-config> for more info.

.. code-block:: yaml

text
gitfs_mountpoint: salt://foo/bar

.. note::

text
The ``salt://`` protocol designation can be left off (in other words,
``foo/bar`` and ``salt://foo/bar`` are equivalent). Assuming a file
``baz.sh`` in the root of a gitfs remote, and the above example mountpoint,
this file would be served up via ``salt://foo/bar/baz.sh``.

.. conf_master:: gitfs_root

gitfs_root


Default: ''

Relative path to a subdirectory within the repository from which Salt should
begin to serve files. This is useful when there are files in the repository
that should not be available to the Salt fileserver. Can be used in conjunction
with :conf_master:gitfs_mountpoint. If used, then from Salt's perspective the
directories above the one specified will be ignored and the relative path will
(for the purposes of gitfs) be considered as the root of the repo.

.. code-block:: yaml

text
gitfs_root: somefolder/otherfolder

.. versionchanged:: 2014.7.0
This option can now be configured on individual repositories as well. See
:ref:here <gitfs-per-remote-config> for more info.

.. conf_master:: gitfs_base

gitfs_base


Default: master

Defines which branch/tag should be used as the base environment.

.. code-block:: yaml

text
gitfs_base: salt

.. versionchanged:: 2014.7.0
This option can now be configured on individual repositories as well. See
:ref:here <gitfs-per-remote-config> for more info.

.. conf_master:: gitfs_saltenv

gitfs_saltenv


.. versionadded:: 2016.11.0

Default: []

Global settings for :ref:per-saltenv configuration parameters <gitfs-per-saltenv-config>. Though per-saltenv configuration parameters are
typically one-off changes specific to a single gitfs remote, and thus more
often configured on a per-remote basis, this parameter can be used to specify
per-saltenv changes which should apply to all remotes. For example, the below
configuration will map the develop branch to the dev saltenv for all
gitfs remotes.

.. code-block:: yaml

text
gitfs_saltenv:
  - dev:
    - ref: develop

.. conf_master:: gitfs_disable_saltenv_mapping

gitfs_disable_saltenv_mapping


.. versionadded:: 2018.3.0

Default: False

When set to True, all saltenv mapping logic is disregarded (aside from
which branch/tag is mapped to the base saltenv). To use any other
environments, they must then be defined using :ref:per-saltenv configuration parameters <gitfs-per-saltenv-config>.

.. code-block:: yaml

text
gitfs_disable_saltenv_mapping: True

.. note::
This is is a global configuration option, see :ref:here <gitfs-per-remote-config> for examples of configuring it for individual
repositories.

.. conf_master:: gitfs_ref_types

gitfs_ref_types


.. versionadded:: 2018.3.0

Default: ['branch', 'tag', 'sha']

This option defines what types of refs are mapped to fileserver environments
(i.e. saltenvs). It also sets the order of preference when there are
ambiguously-named refs (i.e. when a branch and tag both have the same name).
The below example disables mapping of both tags and SHAs, so that only branches
are mapped as saltenvs:

.. code-block:: yaml

text
gitfs_ref_types:
  - branch

.. note::
This is is a global configuration option, see :ref:here <gitfs-per-remote-config> for examples of configuring it for individual
repositories.

.. note::
sha is special in that it will not show up when listing saltenvs (e.g.
with the :py:func:fileserver.envs <salt.runners.fileserver.envs> runner),
but works within states and with :py:func:cp.cache_file <salt.modules.cp.cache_file> to retrieve a file from a specific git SHA.

.. conf_master:: gitfs_saltenv_whitelist

gitfs_saltenv_whitelist


.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
Renamed from gitfs_env_whitelist to gitfs_saltenv_whitelist

Default: []

Used to restrict which environments are made available. Can speed up state runs
if the repos in :conf_master:gitfs_remotes contain many branches/tags. More
information can be found in the :ref:GitFS Walkthrough <gitfs-whitelist-blacklist>.

.. code-block:: yaml

text
gitfs_saltenv_whitelist:
  - base
  - v1.*
  - 'mybranch\d+'

.. conf_master:: gitfs_saltenv_blacklist

gitfs_saltenv_blacklist


.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
Renamed from gitfs_env_blacklist to gitfs_saltenv_blacklist

Default: []

Used to restrict which environments are made available. Can speed up state runs
if the repos in :conf_master:gitfs_remotes contain many branches/tags. More
information can be found in the :ref:GitFS Walkthrough <gitfs-whitelist-blacklist>.

.. code-block:: yaml

text
gitfs_saltenv_blacklist:
  - base
  - v1.*
  - 'mybranch\d+'

.. conf_master:: gitfs_global_lock

gitfs_global_lock


.. versionadded:: 2015.8.9

Default: True

When set to False, if there is an update lock for a gitfs remote and the
pid written to it is not running on the master, the lock file will be
automatically cleared and a new lock will be obtained. When set to True,
Salt will simply log a warning when there is an update lock present.

On single-master deployments, disabling this option can help automatically deal
with instances where the master was shutdown/restarted during the middle of a
gitfs update, leaving a update lock in place.

However, on multi-master deployments with the gitfs cachedir shared via
GlusterFS__, nfs, or another network filesystem, it is strongly recommended
not to disable this option as doing so will cause lock files to be removed if
they were created by a different master.

.. code-block:: yaml

text
# Disable global lock
gitfs_global_lock: False

.. __: http://www.gluster.org/

.. conf_master:: gitfs_update_interval

gitfs_update_interval


.. versionadded:: 2018.3.0

Default: 60

This option defines the default update interval (in seconds) for gitfs remotes.
The update interval can also be set for a single repository via a
:ref:per-remote config option <gitfs-per-remote-config>

.. code-block:: yaml

text
gitfs_update_interval: 120

GitFS Authentication Options


These parameters only currently apply to the pygit2 gitfs provider. Examples of
how to use these can be found in the :ref:GitFS Walkthrough <gitfs-authentication>.

.. conf_master:: gitfs_user

gitfs_user

text
.. versionadded:: 2014.7.0

Default: ``''``

Along with :conf_master:`gitfs_password`, is used to authenticate to HTTPS
remotes.

.. code-block:: yaml

    gitfs_user: git

.. note::
    This is is a global configuration option, see :ref:`here
    <gitfs-per-remote-config>` for examples of configuring it for individual
    repositories.

.. conf_master:: gitfs_password

``gitfs_password``

.. versionadded:: 2014.7.0

Default: ''

Along with :conf_master:gitfs_user, is used to authenticate to HTTPS remotes.
This parameter is not required if the repository does not use authentication.

.. code-block:: yaml

text
gitfs_password: mypassword

.. note::
This is is a global configuration option, see :ref:here <gitfs-per-remote-config> for examples of configuring it for individual
repositories.

.. conf_master:: gitfs_insecure_auth

gitfs_insecure_auth

text
.. versionadded:: 2014.7.0

Default: ``False``

By default, Salt will not authenticate to an HTTP (non-HTTPS) remote. This
parameter enables authentication over HTTP. **Enable this at your own risk.**

.. code-block:: yaml

    gitfs_insecure_auth: True

.. note::
    This is is a global configuration option, see :ref:`here
    <gitfs-per-remote-config>` for examples of configuring it for individual
    repositories.

.. conf_master:: gitfs_pubkey

``gitfs_pubkey``
~~~~~~~~~~~~~~~~

.. versionadded:: 2014.7.0

Default: ``''``

Along with :conf_master:`gitfs_privkey` (and optionally
:conf_master:`gitfs_passphrase`), is used to authenticate to SSH remotes.
Required for SSH remotes.

.. code-block:: yaml

    gitfs_pubkey: /path/to/key.pub

.. note::
    This is is a global configuration option, see :ref:`here
    <gitfs-per-remote-config>` for examples of configuring it for individual
    repositories.

.. conf_master:: gitfs_privkey

``gitfs_privkey``
~~~~~~~~~~~~~~~~~

.. versionadded:: 2014.7.0

Default: ``''``

Along with :conf_master:`gitfs_pubkey` (and optionally
:conf_master:`gitfs_passphrase`), is used to authenticate to SSH remotes.
Required for SSH remotes.

.. code-block:: yaml

    gitfs_privkey: /path/to/key

.. note::
    This is is a global configuration option, see :ref:`here
    <gitfs-per-remote-config>` for examples of configuring it for individual
    repositories.

.. conf_master:: gitfs_passphrase

``gitfs_passphrase``
~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2014.7.0

Default: ``''``

This parameter is optional, required only when the SSH key being used to
authenticate is protected by a passphrase.

.. code-block:: yaml

    gitfs_passphrase: mypassphrase

.. note::
    This is is a global configuration option, see :ref:`here
    <gitfs-per-remote-config>` for examples of configuring it for individual
    repositories.

.. conf_master:: gitfs_refspecs

``gitfs_refspecs``
~~~~~~~~~~~~~~~~~~

.. versionadded:: 2017.7.0

Default: ``['+refs/heads/*:refs/remotes/origin/*', '+refs/tags/*:refs/tags/*']``

When fetching from remote repositories, by default Salt will fetch branches and
tags. This parameter can be used to override the default and specify
alternate refspecs to be fetched. More information on how this feature works
can be found in the :ref:`GitFS Walkthrough <gitfs-custom-refspecs>`.

.. code-block:: yaml

    gitfs_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'
      - '+refs/pull/*/head:refs/remotes/origin/pr/*'
      - '+refs/pull/*/merge:refs/remotes/origin/merge/*'

hgfs: Mercurial Remote File Server Backend
------------------------------------------

.. conf_master:: hgfs_remotes

``hgfs_remotes``
****************

.. versionadded:: 0.17.0

Default: ``[]``

When using the ``hg`` fileserver backend at least one mercurial remote needs to
be defined. The user running the salt master will need read access to the repo.

The repos will be searched in order to find the file requested by a client and
the first repo to have the file will return it. Branches and/or bookmarks are
translated into salt environments, as defined by the
:conf_master:`hgfs_branch_method` parameter.

.. code-block:: yaml

    hgfs_remotes:
      - https://[email protected]/username/reponame

.. note::

    As of 2014.7.0, it is possible to have per-repo versions of the
    :conf_master:`hgfs_root`, :conf_master:`hgfs_mountpoint`,
    :conf_master:`hgfs_base`, and :conf_master:`hgfs_branch_method` parameters.
    For example:

    .. code-block:: yaml

        hgfs_remotes:
          - https://[email protected]/username/repo1
            - base: saltstates
          - https://[email protected]/username/repo2:
            - root: salt
            - mountpoint: salt://foo/bar/baz
          - https://[email protected]/username/repo3:
            - root: salt/states
            - branch_method: mixed

.. conf_master:: hgfs_branch_method

``hgfs_branch_method``
**********************

.. versionadded:: 0.17.0

Default: ``branches``

Defines the objects that will be used as fileserver environments.

* ``branches`` - Only branches and tags will be used
* ``bookmarks`` - Only bookmarks and tags will be used
* ``mixed`` - Branches, bookmarks, and tags will be used

.. code-block:: yaml

    hgfs_branch_method: mixed

.. note::

    Starting in version 2014.1.0, the value of the :conf_master:`hgfs_base`
    parameter defines which branch is used as the ``base`` environment,
    allowing for a ``base`` environment to be used with an
    :conf_master:`hgfs_branch_method` of ``bookmarks``.

    Prior to this release, the ``default`` branch will be used as the ``base``
    environment.

.. conf_master:: hgfs_mountpoint

``hgfs_mountpoint``
*******************

.. versionadded:: 2014.7.0

Default: ``''``

Specifies a path on the salt fileserver which will be prepended to all files
served by hgfs. This option can be used in conjunction with
:conf_master:`hgfs_root`. It can also be configured on a per-remote basis, see
:conf_master:`here <hgfs_remotes>` for more info.

.. code-block:: yaml

    hgfs_mountpoint: salt://foo/bar

.. note::

    The ``salt://`` protocol designation can be left off (in other words,
    ``foo/bar`` and ``salt://foo/bar`` are equivalent). Assuming a file
    ``baz.sh`` in the root of an hgfs remote, this file would be served up via
    ``salt://foo/bar/baz.sh``.

.. conf_master:: hgfs_root

``hgfs_root``
*************

.. versionadded:: 0.17.0

Default: ``''``

Relative path to a subdirectory within the repository from which Salt should
begin to serve files. This is useful when there are files in the repository
that should not be available to the Salt fileserver. Can be used in conjunction
with :conf_master:`hgfs_mountpoint`. If used, then from Salt's perspective the
directories above the one specified will be ignored and the relative path will
(for the purposes of hgfs) be considered as the root of the repo.

.. code-block:: yaml

    hgfs_root: somefolder/otherfolder

.. versionchanged:: 2014.7.0

   Ability to specify hgfs roots on a per-remote basis was added. See
   :conf_master:`here <hgfs_remotes>` for more info.

.. conf_master:: hgfs_base

``hgfs_base``
*************

.. versionadded:: 2014.1.0

Default: ``default``

Defines which branch should be used as the ``base`` environment. Change this if
:conf_master:`hgfs_branch_method` is set to ``bookmarks`` to specify which
bookmark should be used as the ``base`` environment.

.. code-block:: yaml

    hgfs_base: salt

.. conf_master:: hgfs_saltenv_whitelist

``hgfs_saltenv_whitelist``
**************************

.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
    Renamed from ``hgfs_env_whitelist`` to ``hgfs_saltenv_whitelist``

Default: ``[]``

Used to restrict which environments are made available. Can speed up state runs
if your hgfs remotes contain many branches/bookmarks/tags. Full names, globs,
and regular expressions are supported. If using a regular expression, the
expression must match the entire minion ID.

If used, only branches/bookmarks/tags which match one of the specified
expressions will be exposed as fileserver environments.

If used in conjunction with :conf_master:`hgfs_saltenv_blacklist`, then the subset
of branches/bookmarks/tags which match the whitelist but do *not* match the
blacklist will be exposed as fileserver environments.

.. code-block:: yaml

    hgfs_saltenv_whitelist:
      - base
      - v1.*
      - 'mybranch\d+'

.. conf_master:: hgfs_saltenv_blacklist

``hgfs_saltenv_blacklist``
**************************

.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
    Renamed from ``hgfs_env_blacklist`` to ``hgfs_saltenv_blacklist``

Default: ``[]``

Used to restrict which environments are made available. Can speed up state runs
if your hgfs remotes contain many branches/bookmarks/tags. Full names, globs,
and regular expressions are supported. If using a regular expression, the
expression must match the entire minion ID.

If used, branches/bookmarks/tags which match one of the specified expressions
will *not* be exposed as fileserver environments.

If used in conjunction with :conf_master:`hgfs_saltenv_whitelist`, then the subset
of branches/bookmarks/tags which match the whitelist but do *not* match the
blacklist will be exposed as fileserver environments.

.. code-block:: yaml

    hgfs_saltenv_blacklist:
      - base
      - v1.*
      - 'mybranch\d+'

.. conf_master:: hgfs_update_interval

``hgfs_update_interval``
************************

.. versionadded:: 2018.3.0

Default: ``60``

This option defines the update interval (in seconds) for
:conf_master:`hgfs_remotes`.

.. code-block:: yaml

    hgfs_update_interval: 120

svnfs: Subversion Remote File Server Backend
--------------------------------------------

.. conf_master:: svnfs_remotes

``svnfs_remotes``
*****************

.. versionadded:: 0.17.0

Default: ``[]``

When using the ``svn`` fileserver backend at least one subversion remote needs
to be defined. The user running the salt master will need read access to the
repo.

The repos will be searched in order to find the file requested by a client and
the first repo to have the file will return it. The trunk, branches, and tags
become environments, with the trunk being the ``base`` environment.

.. code-block:: yaml

    svnfs_remotes:
      - svn://foo.com/svn/myproject

.. note::

    As of 2014.7.0, it is possible to have per-repo versions of the following
    configuration parameters:

    * :conf_master:`svnfs_root`
    * :conf_master:`svnfs_mountpoint`
    * :conf_master:`svnfs_trunk`
    * :conf_master:`svnfs_branches`
    * :conf_master:`svnfs_tags`

    For example:

    .. code-block:: yaml

        svnfs_remotes:
          - svn://foo.com/svn/project1
          - svn://foo.com/svn/project2:
            - root: salt
            - mountpoint: salt://foo/bar/baz
          - svn//foo.com/svn/project3:
            - root: salt/states
            - branches: branch
            - tags: tag

.. conf_master:: svnfs_mountpoint

``svnfs_mountpoint``
********************

.. versionadded:: 2014.7.0

Default: ``''``

Specifies a path on the salt fileserver which will be prepended to all files
served by hgfs. This option can be used in conjunction with
:conf_master:`svnfs_root`. It can also be configured on a per-remote basis, see
:conf_master:`here <svnfs_remotes>` for more info.

.. code-block:: yaml

    svnfs_mountpoint: salt://foo/bar

.. note::

    The ``salt://`` protocol designation can be left off (in other words,
    ``foo/bar`` and ``salt://foo/bar`` are equivalent). Assuming a file
    ``baz.sh`` in the root of an svnfs remote, this file would be served up via
    ``salt://foo/bar/baz.sh``.

.. conf_master:: svnfs_root

``svnfs_root``
**************

.. versionadded:: 0.17.0

Default: ``''``

Relative path to a subdirectory within the repository from which Salt should
begin to serve files. This is useful when there are files in the repository
that should not be available to the Salt fileserver. Can be used in conjunction
with :conf_master:`svnfs_mountpoint`. If used, then from Salt's perspective the
directories above the one specified will be ignored and the relative path will
(for the purposes of svnfs) be considered as the root of the repo.

.. code-block:: yaml

    svnfs_root: somefolder/otherfolder

.. versionchanged:: 2014.7.0

   Ability to specify svnfs roots on a per-remote basis was added. See
   :conf_master:`here <svnfs_remotes>` for more info.

.. conf_master:: svnfs_trunk

``svnfs_trunk``
***************

.. versionadded:: 2014.7.0

Default: ``trunk``

Path relative to the root of the repository where the trunk is located. Can
also be configured on a per-remote basis, see :conf_master:`here
<svnfs_remotes>` for more info.

.. code-block:: yaml

    svnfs_trunk: trunk

.. conf_master:: svnfs_branches

``svnfs_branches``
******************

.. versionadded:: 2014.7.0

Default: ``branches``

Path relative to the root of the repository where the branches are located. Can
also be configured on a per-remote basis, see :conf_master:`here
<svnfs_remotes>` for more info.

.. code-block:: yaml

    svnfs_branches: branches

.. conf_master:: svnfs_tags

``svnfs_tags``
**************

.. versionadded:: 2014.7.0

Default: ``tags``

Path relative to the root of the repository where the tags are located. Can
also be configured on a per-remote basis, see :conf_master:`here
<svnfs_remotes>` for more info.

.. code-block:: yaml

    svnfs_tags: tags

.. conf_master:: svnfs_saltenv_whitelist

``svnfs_saltenv_whitelist``
***************************

.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
    Renamed from ``svnfs_env_whitelist`` to ``svnfs_saltenv_whitelist``

Default: ``[]``

Used to restrict which environments are made available. Can speed up state runs
if your svnfs remotes contain many branches/tags. Full names, globs, and
regular expressions are supported. If using a regular expression, the expression
must match the entire minion ID.

If used, only branches/tags which match one of the specified expressions will
be exposed as fileserver environments.

If used in conjunction with :conf_master:`svnfs_saltenv_blacklist`, then the subset
of branches/tags which match the whitelist but do *not* match the blacklist
will be exposed as fileserver environments.

.. code-block:: yaml

    svnfs_saltenv_whitelist:
      - base
      - v1.*
      - 'mybranch\d+'

.. conf_master:: svnfs_saltenv_blacklist

``svnfs_saltenv_blacklist``
***************************

.. versionadded:: 2014.7.0
.. versionchanged:: 2018.3.0
    Renamed from ``svnfs_env_blacklist`` to ``svnfs_saltenv_blacklist``

Default: ``[]``

Used to restrict which environments are made available. Can speed up state runs
if your svnfs remotes contain many branches/tags. Full names, globs, and
regular expressions are supported. If using a regular expression, the
expression must match the entire minion ID.

If used, branches/tags which match one of the specified expressions will *not*
be exposed as fileserver environments.

If used in conjunction with :conf_master:`svnfs_saltenv_whitelist`, then the subset
of branches/tags which match the whitelist but do *not* match the blacklist
will be exposed as fileserver environments.

.. code-block:: yaml

    svnfs_saltenv_blacklist:
      - base
      - v1.*
      - 'mybranch\d+'

.. conf_master:: svnfs_update_interval

``svnfs_update_interval``
*************************

.. versionadded:: 2018.3.0

Default: ``60``

This option defines the update interval (in seconds) for
:conf_master:`svnfs_remotes`.

.. code-block:: yaml

    svnfs_update_interval: 120

minionfs: MinionFS Remote File Server Backend
---------------------------------------------

.. conf_master:: minionfs_env

``minionfs_env``
****************

.. versionadded:: 2014.7.0

Default: ``base``

Environment from which MinionFS files are made available.

.. code-block:: yaml

    minionfs_env: minionfs

.. conf_master:: minionfs_mountpoint

``minionfs_mountpoint``
***********************

.. versionadded:: 2014.7.0

Default: ``''``

Specifies a path on the salt fileserver from which minionfs files are served.

.. code-block:: yaml

    minionfs_mountpoint: salt://foo/bar

.. note::

    The ``salt://`` protocol designation can be left off (in other words,
    ``foo/bar`` and ``salt://foo/bar`` are equivalent).

.. conf_master:: minionfs_whitelist

``minionfs_whitelist``
**********************

.. versionadded:: 2014.7.0

Default: ``[]``

Used to restrict which minions' pushed files are exposed via minionfs. If using
a regular expression, the expression must match the entire minion ID.

If used, only the pushed files from minions which match one of the specified
expressions will be exposed.

If used in conjunction with :conf_master:`minionfs_blacklist`, then the subset
of hosts which match the whitelist but do *not* match the blacklist will be
exposed.

.. code-block:: yaml

    minionfs_whitelist:
      - server01
      - dev*
      - 'mail\d+.mydomain.tld'

.. conf_master:: minionfs_blacklist

``minionfs_blacklist``
**********************

.. versionadded:: 2014.7.0

Default: ``[]``

Used to restrict which minions' pushed files are exposed via minionfs. If using
a regular expression, the expression must match the entire minion ID.

If used, only the pushed files from minions which match one of the specified
expressions will *not* be exposed.

If used in conjunction with :conf_master:`minionfs_whitelist`, then the subset
of hosts which match the whitelist but do *not* match the blacklist will be
exposed.

.. code-block:: yaml

    minionfs_blacklist:
      - server01
      - dev*
      - 'mail\d+.mydomain.tld'

.. conf_master:: minionfs_update_interval

``minionfs_update_interval``
****************************

.. versionadded:: 2018.3.0

Default: ``60``

This option defines the update interval (in seconds) for :ref:`MinionFS
<tutorial-minionfs>`.

.. note::
    Since :ref:`MinionFS <tutorial-minionfs>` consists of files local to the
    master, the update process for this fileserver backend just reaps the cache
    for this backend.

.. code-block:: yaml

    minionfs_update_interval: 120

s3fs: S3 File Server Backend
----------------------------

.. versionadded:: 0.16.0

See the :mod:`s3fs documentation <salt.fileserver.s3fs>` for usage examples.

.. conf_master:: s3fs_update_interval

``s3fs_update_interval``
************************

.. versionadded:: 2018.3.0

Default: ``60``

This option defines the update interval (in seconds) for s3fs.

.. code-block:: yaml

    s3fs_update_interval: 120

``fileserver_interval``
***********************

.. versionadded:: 3006.0

Default: ``3600``

Defines how often to restart the master's FilesServerUpdate process.

.. code-block:: yaml

    fileserver_interval: 9600


.. _pillar-configuration-master:

Pillar Configuration
====================

.. conf_master:: pillar_roots

``pillar_roots``
----------------

.. versionchanged:: 3005

Default:

.. code-block:: yaml

    base:
      - /srv/pillar

Set the environments and directories used to hold pillar sls data. This
configuration is the same as :conf_master:`file_roots`:

As of 2017.7.5 and 2018.3.1, it is possible to have `__env__` as a catch-all environment.

Example:

.. code-block:: yaml

    pillar_roots:
      base:
        - /srv/pillar
      dev:
        - /srv/pillar/dev
      prod:
        - /srv/pillar/prod
      __env__:
        - /srv/pillar/others

Taking dynamic environments one step further, ``__env__`` can also be used in
the ``pillar_roots`` filesystem path as of version 3005. It will be replaced
with the actual ``pillarenv`` and searched for Pillar data to provide to the
minion. Note this substitution ONLY occurs for the ``__env__`` environment. For
instance, this configuration:

.. code-block:: yaml

    pillar_roots:
      __env__:
        - /srv/__env__/pillar

is equivalent to this static configuration:

.. code-block:: yaml

    pillar_roots:
      dev:
        - /srv/dev/pillar
      test:
        - /srv/test/pillar
      prod:
        - /srv/prod/pillar

.. conf_master:: on_demand_ext_pillar

``on_demand_ext_pillar``
------------------------

.. versionadded:: 2016.3.6,2016.11.3,2017.7.0

Default: ``['libvirt', 'virtkey']``

The external pillars permitted to be used on-demand using :py:func:`pillar.ext
<salt.modules.pillar.ext>`.

.. code-block:: yaml

    on_demand_ext_pillar:
      - libvirt
      - virtkey
      - git

.. warning::
    This will allow minions to request specific pillar data via
    :py:func:`pillar.ext <salt.modules.pillar.ext>`, and may be considered a
    security risk. However, pillar data generated in this way will not affect
    the :ref:`in-memory pillar data <pillar-in-memory>`, so this risk is
    limited to instances in which states/modules/etc. (built-in or custom) rely
    upon pillar data generated by :py:func:`pillar.ext
    <salt.modules.pillar.ext>`.

.. conf_master:: decrypt_pillar

``decrypt_pillar``
------------------

.. versionadded:: 2017.7.0

Default: ``[]``

A list of paths to be recursively decrypted during pillar compilation.

.. code-block:: yaml

    decrypt_pillar:
      - 'foo:bar': gpg
      - 'lorem:ipsum:dolor'

Entries in this list can be formatted either as a simple string, or as a
key/value pair, with the key being the pillar location, and the value being the
renderer to use for pillar decryption. If the former is used, the renderer
specified by :conf_master:`decrypt_pillar_default` will be used.

.. conf_master:: decrypt_pillar_delimiter

``decrypt_pillar_delimiter``
----------------------------

.. versionadded:: 2017.7.0

Default: ``:``

The delimiter used to distinguish nested data structures in the
:conf_master:`decrypt_pillar` option.

.. code-block:: yaml

    decrypt_pillar_delimiter: '|'
    decrypt_pillar:
      - 'foo|bar': gpg
      - 'lorem|ipsum|dolor'

.. conf_master:: decrypt_pillar_default

``decrypt_pillar_default``
--------------------------

.. versionadded:: 2017.7.0

Default: ``gpg``

The default renderer used for decryption, if one is not specified for a given
pillar key in :conf_master:`decrypt_pillar`.

.. code-block:: yaml

    decrypt_pillar_default: my_custom_renderer

.. conf_master:: decrypt_pillar_renderers

``decrypt_pillar_renderers``
----------------------------

.. versionadded:: 2017.7.0

Default: ``['gpg']``

List of renderers which are permitted to be used for pillar decryption.

.. code-block:: yaml

    decrypt_pillar_renderers:
      - gpg
      - my_custom_renderer

.. conf_master:: gpg_decrypt_must_succeed

``gpg_decrypt_must_succeed``
----------------------------

.. versionadded:: 3005

Default: ``False``

If this is ``True`` and the ciphertext could not be decrypted, then an error is
raised.

Sending the ciphertext through basically is *never* desired, for example if a
state is setting a database password from pillar and gpg rendering fails, then
the state will update the password to the ciphertext, which by definition is
not encrypted.

.. warning::

    The value defaults to ``False`` for backwards compatibility.  In the
    ``Chlorine`` release, this option will default to ``True``.

.. code-block:: yaml

    gpg_decrypt_must_succeed: False

.. conf_master:: pillar_opts

``pillar_opts``
---------------

Default: ``False``

The ``pillar_opts`` option adds the master configuration file data to a dict in
the pillar called ``master``. This can be used to set simple configurations in
the master config file that can then be used on minions.

Note that setting this option to ``True`` means the master config file will be
included in all minion's pillars. While this makes global configuration of services
and systems easy, it may not be desired if sensitive data is stored in the master
configuration.

.. code-block:: yaml

    pillar_opts: False

.. conf_master:: pillar_safe_render_error

``pillar_safe_render_error``
----------------------------

Default: ``True``

The pillar_safe_render_error option prevents the master from passing pillar
render errors to the minion. This is set on by default because the error could
contain templating data which would give that minion information it shouldn't
have, like a password! When set ``True`` the error message will only show:

.. code-block:: shell

    Rendering SLS 'my.sls' failed. Please see master log for details.

.. code-block:: yaml

    pillar_safe_render_error: True

.. _master-configuration-ext-pillar:

.. conf_master:: ext_pillar

``ext_pillar``
--------------

The ext_pillar option allows for any number of external pillar interfaces to be
called when populating pillar data. The configuration is based on ext_pillar
functions. The available ext_pillar functions can be found herein:

:blob:`salt/pillar`

By default, the ext_pillar interface is not configured to run.

Default: ``[]``

.. code-block:: yaml

    ext_pillar:
      - hiera: /etc/hiera.yaml
      - cmd_yaml: cat /etc/salt/yaml
      - reclass:
          inventory_base_uri: /etc/reclass

There are additional details at :ref:`salt-pillars`

.. conf_master:: ext_pillar_first

``ext_pillar_first``
--------------------

.. versionadded:: 2015.5.0

Default: ``False``

This option allows for external pillar sources to be evaluated before
:conf_master:`pillar_roots`. External pillar data is evaluated separately from
:conf_master:`pillar_roots` pillar data, and then both sets of pillar data are
merged into a single pillar dictionary, so the value of this config option will
have an impact on which key "wins" when there is one of the same name in both
the external pillar data and :conf_master:`pillar_roots` pillar data. By
setting this option to ``True``, ext_pillar keys will be overridden by
:conf_master:`pillar_roots`, while leaving it as ``False`` will allow
ext_pillar keys to override those from :conf_master:`pillar_roots`.

.. note::
    For a while, this config option did not work as specified above, because of
    a bug in Pillar compilation. This bug has been resolved in version 2016.3.4
    and later.

.. code-block:: yaml

    ext_pillar_first: False

.. conf_master:: pillarenv_from_saltenv

``pillarenv_from_saltenv``
--------------------------

Default: ``False``

When set to ``True``, the :conf_master:`pillarenv` value will assume the value
of the effective saltenv when running states. This essentially makes ``salt-run
pillar.show_pillar saltenv=dev`` equivalent to ``salt-run pillar.show_pillar
saltenv=dev pillarenv=dev``. If :conf_master:`pillarenv` is set on the CLI, it
will override this option.

.. code-block:: yaml

    pillarenv_from_saltenv: True

.. note::
    For salt remote execution commands this option should be set in the Minion
    configuration instead.

.. conf_master:: pillar_raise_on_missing

``pillar_raise_on_missing``
---------------------------

.. versionadded:: 2015.5.0

Default: ``False``

Set this option to ``True`` to force a ``KeyError`` to be raised whenever an
attempt to retrieve a named value from pillar fails. When this option is set
to ``False``, the failed attempt returns an empty string.

.. _git-pillar-config-opts:

Git External Pillar (git_pillar) Configuration Options
------------------------------------------------------

.. conf_master:: git_pillar_provider

``git_pillar_provider``
***********************

.. versionadded:: 2015.8.0

Specify the provider to be used for git_pillar. Must be either ``pygit2`` or
``gitpython``. If unset, then both will be tried in that same order, and the
first one with a compatible version installed will be the provider that is
used.

.. code-block:: yaml

    git_pillar_provider: gitpython

.. conf_master:: git_pillar_base

``git_pillar_base``
*******************

.. versionadded:: 2015.8.0

Default: ``master``

If the desired branch matches this value, and the environment is omitted from
the git_pillar configuration, then the environment for that git_pillar remote
will be ``base``. For example, in the configuration below, the ``foo``
branch/tag would be assigned to the ``base`` environment, while ``bar`` would
be mapped to the ``bar`` environment.

.. code-block:: yaml

    git_pillar_base: foo

    ext_pillar:
      - git:
        - foo https://mygitserver/git-pillar.git
        - bar https://mygitserver/git-pillar.git

.. conf_master:: git_pillar_branch

``git_pillar_branch``
*********************

.. versionadded:: 2015.8.0

Default: ``master``

If the branch is omitted from a git_pillar remote, then this branch will be
used instead. For example, in the configuration below, the first two remotes
would use the ``pillardata`` branch/tag, while the third would use the ``foo``
branch/tag.

.. code-block:: yaml

    git_pillar_branch: pillardata

    ext_pillar:
      - git:
        - https://mygitserver/pillar1.git
        - https://mygitserver/pillar2.git:
          - root: pillar
        - foo https://mygitserver/pillar3.git

.. conf_master:: git_pillar_env

``git_pillar_env``
******************

.. versionadded:: 2015.8.0

Default: ``''`` (unset)

Environment to use for git_pillar remotes. This is normally derived from the
branch/tag (or from a per-remote ``env`` parameter), but if set this will
override the process of deriving the env from the branch/tag name. For example,
in the configuration below the ``foo`` branch would be assigned to the ``base``
environment, while the ``bar`` branch would need to explicitly have ``bar``
configured as its environment to keep it from also being mapped to the
``base`` environment.

.. code-block:: yaml

    git_pillar_env: base

    ext_pillar:
      - git:
        - foo https://mygitserver/git-pillar.git
        - bar https://mygitserver/git-pillar.git:
          - env: bar

For this reason, this option is recommended to be left unset, unless the use
case calls for all (or almost all) of the git_pillar remotes to use the same
environment irrespective of the branch/tag being used.

.. conf_master:: git_pillar_root

``git_pillar_root``
*******************

.. versionadded:: 2015.8.0

Default: ``''``

Path relative to the root of the repository where the git_pillar top file and
SLS files are located. In the below configuration, the pillar top file and SLS
files would be looked for in a subdirectory called ``pillar``.

.. code-block:: yaml

    git_pillar_root: pillar

    ext_pillar:
      - git:
        - master https://mygitserver/pillar1.git
        - master https://mygitserver/pillar2.git

.. note::

    This is a global option. If only one or two repos need to have their files
    sourced from a subdirectory, then :conf_master:`git_pillar_root` can be
    omitted and the root can be specified on a per-remote basis, like so:

    .. code-block:: yaml

        ext_pillar:
          - git:
            - master https://mygitserver/pillar1.git
            - master https://mygitserver/pillar2.git:
              - root: pillar

    In this example, for the first remote the top file and SLS files would be
    looked for in the root of the repository, while in the second remote the
    pillar data would be retrieved from the ``pillar`` subdirectory.

.. conf_master:: git_pillar_ssl_verify

``git_pillar_ssl_verify``
*************************

.. versionadded:: 2015.8.0
.. versionchanged:: 2016.11.0

Default: ``False``

Specifies whether or not to ignore SSL certificate errors when contacting the
remote repository. The ``False`` setting is useful if you're using a
git repo that uses a self-signed certificate. However, keep in mind that
setting this to anything other ``True`` is a considered insecure, and using an
SSH-based transport (if available) may be a better option.

In the 2016.11.0 release, the default config value changed from ``False`` to
``True``.

.. code-block:: yaml

    git_pillar_ssl_verify: True

.. note::
    pygit2 only supports disabling SSL verification in versions 0.23.2 and
    newer.

.. conf_master:: git_pillar_global_lock

``git_pillar_global_lock``
**************************

.. versionadded:: 2015.8.9

Default: ``True``

When set to ``False``, if there is an update/checkout lock for a git_pillar
remote and the pid written to it is not running on the master, the lock file
will be automatically cleared and a new lock will be obtained. When set to
``True``, Salt will simply log a warning when there is an lock present.

On single-master deployments, disabling this option can help automatically deal
with instances where the master was shutdown/restarted during the middle of a
git_pillar update/checkout, leaving a lock in place.

However, on multi-master deployments with the git_pillar cachedir shared via
`GlusterFS`__, nfs, or another network filesystem, it is strongly recommended
not to disable this option as doing so will cause lock files to be removed if
they were created by a different master.

.. code-block:: yaml

    # Disable global lock
    git_pillar_global_lock: False

.. __: http://www.gluster.org/

.. conf_master:: git_pillar_includes

``git_pillar_includes``
***********************

.. versionadded:: 2017.7.0

Default: ``True``

Normally, when processing :ref:`git_pillar remotes
<git-pillar-configuration>`, if more than one repo under the same ``git``
section in the ``ext_pillar`` configuration refers to the same pillar
environment, then each repo in a given environment will have access to the
other repos' files to be referenced in their top files. However, it may be
desirable to disable this behavior. If so, set this value to ``False``.

For a more detailed examination of how includes work, see :ref:`this
explanation <git-pillar-multiple-remotes>` from the git_pillar documentation.

.. code-block:: yaml

    git_pillar_includes: False

``git_pillar_update_interval``
******************************

.. versionadded:: 3000

Default: ``60``

This option defines the default update interval (in seconds) for git_pillar
remotes. The update is handled within the global loop, hence
``git_pillar_update_interval`` should be a multiple of ``loop_interval``.

.. code-block:: yaml

    git_pillar_update_interval: 120

.. _git-ext-pillar-auth-opts:

Git External Pillar Authentication Options
******************************************

These parameters only currently apply to the ``pygit2``
:conf_master:`git_pillar_provider`. Authentication works the same as it does
in gitfs, as outlined in the :ref:`GitFS Walkthrough <gitfs-authentication>`,
though the global configuration options are named differently to reflect that
they are for git_pillar instead of gitfs.

.. conf_master:: git_pillar_user

``git_pillar_user``
~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`git_pillar_password`, is used to authenticate to HTTPS
remotes.

.. code-block:: yaml

    git_pillar_user: git

.. conf_master:: git_pillar_password

``git_pillar_password``

.. versionadded:: 2015.8.0

Default: ''

Along with :conf_master:git_pillar_user, is used to authenticate to HTTPS
remotes. This parameter is not required if the repository does not use
authentication.

.. code-block:: yaml

text
git_pillar_password: mypassword

.. conf_master:: git_pillar_insecure_auth

git_pillar_insecure_auth

text
.. versionadded:: 2015.8.0

Default: ``False``

By default, Salt will not authenticate to an HTTP (non-HTTPS) remote. This
parameter enables authentication over HTTP. **Enable this at your own risk.**

.. code-block:: yaml

    git_pillar_insecure_auth: True

.. conf_master:: git_pillar_pubkey

``git_pillar_pubkey``
~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`git_pillar_privkey` (and optionally
:conf_master:`git_pillar_passphrase`), is used to authenticate to SSH remotes.

.. code-block:: yaml

    git_pillar_pubkey: /path/to/key.pub

.. conf_master:: git_pillar_privkey

``git_pillar_privkey``
~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`git_pillar_pubkey` (and optionally
:conf_master:`git_pillar_passphrase`), is used to authenticate to SSH remotes.

.. code-block:: yaml

    git_pillar_privkey: /path/to/key

.. conf_master:: git_pillar_passphrase

``git_pillar_passphrase``
~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2015.8.0

Default: ``''``

This parameter is optional, required only when the SSH key being used to
authenticate is protected by a passphrase.

.. code-block:: yaml

    git_pillar_passphrase: mypassphrase

.. conf_master:: git_pillar_refspecs

``git_pillar_refspecs``
~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2017.7.0

Default: ``['+refs/heads/*:refs/remotes/origin/*', '+refs/tags/*:refs/tags/*']``

When fetching from remote repositories, by default Salt will fetch branches and
tags. This parameter can be used to override the default and specify
alternate refspecs to be fetched. This parameter works similarly to its
:ref:`GitFS counterpart <gitfs-custom-refspecs>`, in that it can be
configured both globally and for individual remotes.

.. code-block:: yaml

    git_pillar_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'
      - '+refs/pull/*/head:refs/remotes/origin/pr/*'
      - '+refs/pull/*/merge:refs/remotes/origin/merge/*'

.. conf_master:: git_pillar_verify_config

``git_pillar_verify_config``
----------------------------

.. versionadded:: 2017.7.0

Default: ``True``

By default, as the master starts it performs some sanity checks on the
configured git_pillar repositories. If any of these sanity checks fail (such as
when an invalid configuration is used), the master daemon will abort.

To skip these sanity checks, set this option to ``False``.

.. code-block:: yaml

    git_pillar_verify_config: False

.. _pillar-merging-opts:

Pillar Merging Options
----------------------

.. conf_master:: pillar_source_merging_strategy

``pillar_source_merging_strategy``
**********************************

.. versionadded:: 2014.7.0

Default: ``smart``

The pillar_source_merging_strategy option allows you to configure merging
strategy between different sources. It accepts 5 values:

* ``none``:

  It will not do any merging at all and only parse the pillar data from the passed environment and 'base' if no environment was specified.

  .. versionadded:: 2016.3.4

* ``recurse``:

  It will recursively merge data. For example, theses 2 sources:

  .. code-block:: yaml

      foo: 42
      bar:
          element1: True

  .. code-block:: yaml

      bar:
          element2: True
      baz: quux

  will be merged as:

  .. code-block:: yaml

      foo: 42
      bar:
          element1: True
          element2: True
      baz: quux

* ``aggregate``:

  instructs aggregation of elements between sources that use the #!yamlex renderer.

  For example, these two documents:

  .. code-block:: yaml

      foo: 42
      bar: !aggregate {
        element1: True
      }
      baz: !aggregate quux

  .. code-block:: yaml

      bar: !aggregate {
        element2: True
      }
      baz: !aggregate quux2

  will be merged as:

  .. code-block:: yaml

      foo: 42
      bar:
        element1: True
        element2: True
      baz:
        - quux
        - quux2

  .. note::
      This requires that the :ref:`render pipeline <renderers-composing>`
      defined in the :conf_master:`renderer` master configuration ends in
      ``yamlex``.

* ``overwrite``:

  Will use the behaviour of the 2014.1 branch and earlier.

  Overwrites elements according the order in which they are processed.

  First pillar processed:

  .. code-block:: yaml

      A:
        first_key: blah
        second_key: blah

  Second pillar processed:

  .. code-block:: yaml

      A:
        third_key: blah
        fourth_key: blah

  will be merged as:

  .. code-block:: yaml

      A:
        third_key: blah
        fourth_key: blah

* ``smart`` (default):

  Guesses the best strategy based on the "renderer" setting.

.. note::
    In order for yamlex based features such as ``!aggregate`` to work as expected
    across documents using the default ``smart`` merge strategy, the :conf_master:`renderer`
    config option must be set to ``jinja|yamlex`` or similar.

.. conf_master:: pillar_merge_lists

``pillar_merge_lists``
**********************

.. versionadded:: 2015.8.0

Default: ``False``

Recursively merge lists by aggregating them instead of replacing them.

.. code-block:: yaml

    pillar_merge_lists: False

.. conf_master:: pillar_mask_output

``pillar_mask_output``
**********************

.. versionadded:: 3008.3

Default: ``True``

Changes the *default* behavior of :py:func:`pillar.items
<salt.modules.pillar.items>` when a caller doesn't explicitly pass
``unmask``. When ``True`` (the default), ``pillar.items`` returns masked
values (``**********``) by default, matching :py:func:`pillar.get
<salt.modules.pillar.get>` and friends. Set to ``False`` to make
``pillar.items`` default to returning real, unmasked values instead —
useful for sites relying on the pre-masking ``pillar.items`` behavior.

This option does **not** disable pillar masking elsewhere: ``pillar.get``,
``pillar.item``, ``pillar.raw``, ``pillar.ext``, ``no_log`` state output,
and the general CLI output safety net are unaffected and keep redacting by
default regardless of this setting. Callers of ``pillar.items`` can always
override the default explicitly with ``unmask=True``/``unmask=False``.

.. code-block:: yaml

    pillar_mask_output: True

.. conf_master:: pillar_includes_override_sls

``pillar_includes_override_sls``
********************************

.. versionadded:: 2017.7.6,2018.3.1

Default: ``False``

Prior to version 2017.7.3, keys from :ref:`pillar includes `
would be merged on top of the pillar SLS. Since 2017.7.3, the includes are
merged together and then the pillar SLS is merged on top of that.

Set this option to ``True`` to return to the old behavior.

.. code-block:: yaml

    pillar_includes_override_sls: True

.. _pillar-cache-opts:

Pillar Cache Options
--------------------

.. conf_master:: pillar_cache

``pillar_cache``
****************

.. versionadded:: 2015.8.8

Default: ``False``

A master can cache pillars locally to bypass the expense of having to render them
for each minion on every request. This feature should only be enabled in cases
where pillar rendering time is known to be unsatisfactory and any attendant security
concerns about storing pillars in a master cache have been addressed.

When enabling this feature, be certain to read through the additional ``pillar_cache_*``
configuration options to fully understand the tunable parameters and their implications.

.. code-block:: yaml

    pillar_cache: False

.. note::

    Setting ``pillar_cache: True`` has no effect on
    :ref:`targeting minions with pillar <targeting-pillar>`.

.. conf_master:: pillar_cache_ttl

``pillar_cache_ttl``
********************

.. versionadded:: 2015.8.8

Default: ``3600``

If and only if a master has set ``pillar_cache: True``, the cache TTL controls the amount
of time, in seconds, before the cache is considered invalid by a master and a fresh
pillar is recompiled and stored.
The cache TTL does not prevent pillar cache from being refreshed before its TTL expires.

.. conf_master:: pillar_cache_backend

``pillar_cache_backend``
************************

.. versionadded:: 2015.8.8

Default: ``disk``

If an only if a master has set ``pillar_cache: True``, one of several storage providers
can be utilized:

* ``disk`` (default):

  The default storage backend. This caches rendered pillars to the master cache.
  Rendered pillars are serialized and deserialized as ``msgpack`` structures for speed.
  Note that pillars are stored UNENCRYPTED. Ensure that the master cache has permissions
  set appropriately (sane defaults are provided).

* ``memory`` [EXPERIMENTAL]:

  An optional backend for pillar caches which uses a pure-Python
  in-memory data structure for maximal performance. There are several caveats,
  however. First, because each master worker contains its own in-memory cache,
  there is no guarantee of cache consistency between minion requests. This
  works best in situations where the pillar rarely if ever changes. Secondly,
  and perhaps more importantly, this means that unencrypted pillars will
  be accessible to any process which can examine the memory of the ``salt-master``!
  This may represent a substantial security risk.

.. code-block:: yaml

    pillar_cache_backend: disk


Master Reactor Settings
=======================

.. conf_master:: reactor

``reactor``
-----------

Default: ``[]``

Defines a salt reactor. See the :ref:`Reactor <reactor>` documentation for more
information.

.. code-block:: yaml

    reactor:
      - 'salt/minion/*/start':
        - salt://reactor/startup_tasks.sls

.. conf_master:: reactor_refresh_interval

``reactor_refresh_interval``
----------------------------

Default: ``60``

The TTL for the cache of the reactor configuration.

.. code-block:: yaml

    reactor_refresh_interval: 60

.. conf_master:: reactor_worker_threads

``reactor_worker_threads``
--------------------------

Default: ``10``

The number of workers for the runner/wheel in the reactor.

.. code-block:: yaml

    reactor_worker_threads: 10

.. conf_master:: reactor_worker_hwm

``reactor_worker_hwm``
----------------------

Default: ``10000``

The queue size for workers in the reactor.

.. code-block:: yaml

    reactor_worker_hwm: 10000


.. _salt-api-master-settings:

Salt-API Master Settings
========================

There are some settings for :ref:`salt-api <netapi-introduction>` that can be
configured on the Salt Master.

.. conf_master:: api_logfile

``api_logfile``
---------------

Default: ``/var/log/salt/api``

The logfile location for ``salt-api``.

.. code-block:: yaml

    api_logfile: /var/log/salt/api

.. conf_master:: api_pidfile

``api_pidfile``
---------------

Default: /var/run/salt-api.pid

If this master will be running ``salt-api``, specify the pidfile of the
``salt-api`` daemon.

.. code-block:: yaml

    api_pidfile: /var/run/salt-api.pid

.. conf_master:: rest_timeout

``rest_timeout``
----------------

Default: ``300``

Used by ``salt-api`` for the master requests timeout.

.. code-block:: yaml

    rest_timeout: 300

.. conf_master:: netapi_disable_clients

``netapi_enable_clients``
--------------------------

.. versionadded:: 3006.0

Default: ``[]``

Used by ``salt-api`` to enable access to the listed clients. Unless a
client is addded to this list, requests will be rejected before
authentication is attempted or processing of the low state occurs.

This can be used to only expose the required functionality via
``salt-api``.

Configuration with all possible clients enabled:

.. code-block:: yaml

    netapi_enable_clients:
      - local
      - local_async
      - local_batch
      - local_subset
      - runner
      - runner_async
      - ssh
      - wheel
      - wheel_async

.. note::

    Enabling all clients is not recommended - only enable the
    clients that provide the functionality required.

.. _syndic-server-settings:

Syndic Server Settings
======================

A Salt syndic is a Salt master used to pass commands from a higher Salt master
to minions below the syndic. Using the syndic is simple. If this is a master
that will have syndic servers(s) below it, set the ``order_masters`` setting to
``True``.

If this is a master that will be running a syndic daemon for passthrough the
``syndic_master`` setting needs to be set to the location of the master server.

Do not forget that, in other words, it means that it shares with the local minion
its ID and PKI directory.

.. conf_master:: order_masters

``order_masters``
-----------------

Default: ``False``

Extra data needs to be sent with publications if the master is controlling a
lower level master via a syndic minion. If this is the case the order_masters
value must be set to True

.. code-block:: yaml

    order_masters: False

.. conf_master:: syndic_master

``syndic_master``
-----------------

.. versionchanged:: 2016.3.5,2016.11.1

    Set default higher level master address.

Default: ``masterofmasters``

If this master will be running the ``salt-syndic`` to connect to a higher level
master, specify the higher level master with this configuration value.

.. code-block:: yaml

    syndic_master: masterofmasters

You can optionally connect a syndic to multiple higher level masters by
setting the ``syndic_master`` value to a list:

.. code-block:: yaml

    syndic_master:
      - masterofmasters1
      - masterofmasters2

Each higher level master must be set up in a multi-master configuration.

.. conf_master:: syndic_master_port

``syndic_master_port``
----------------------

Default: ``4506``

If this master will be running the ``salt-syndic`` to connect to a higher level
master, specify the higher level master port with this configuration value.

.. code-block:: yaml

    syndic_master_port: 4506

.. conf_master:: syndic_pidfile

``syndic_pidfile``
------------------

Default: ``/var/run/salt-syndic.pid``

If this master will be running the ``salt-syndic`` to connect to a higher level
master, specify the pidfile of the syndic daemon.

.. code-block:: yaml

    syndic_pidfile: /var/run/syndic.pid

.. conf_master:: syndic_log_file

``syndic_log_file``
-------------------

Default: ``/var/log/salt/syndic``

If this master will be running the ``salt-syndic`` to connect to a higher level
master, specify the log file of the syndic daemon.

.. code-block:: yaml

    syndic_log_file: /var/log/salt-syndic.log

.. conf_master:: syndic_failover

``syndic_failover``
-------------------

.. versionadded:: 2016.3.0

Default: ``random``

The behaviour of the multi-syndic when connection to a master of masters failed.
Can specify ``random`` (default) or ``ordered``. If set to ``random``, masters
will be iterated in random order. If ``ordered`` is specified, the configured
order will be used.

.. code-block:: yaml

    syndic_failover: random

.. conf_master:: syndic_wait

``syndic_wait``
---------------

Default: ``5``

The number of seconds for the salt client to wait for additional syndics to
check in with their lists of expected minions before giving up.

.. code-block:: yaml

    syndic_wait: 5

.. conf_master:: syndic_forward_all_events

``syndic_forward_all_events``
-----------------------------

.. versionadded:: 2017.7.0

Default: ``False``

Option on multi-syndic or single when connected to multiple masters to be able to
send events to all connected masters.

.. code-block:: yaml

    syndic_forward_all_events: False

.. conf_master:: syndic_retries

``syndic_retries``
------------------

.. versionadded:: 3006.16

Default: ``3``

The maximum number of retries for a syndic return attempt to the Master of Masters.
If multiple Master of Masters listed, it will attempt this number of retries for
each master in the list.

.. code-block:: yaml

    syndic_retries: 4

.. _peer-publish-settings:

Peer Publish Settings
=====================

Salt minions can send commands to other minions, but only if the minion is
allowed to. By default "Peer Publication" is disabled, and when enabled it
is enabled for specific minions and specific commands. This allows secure
compartmentalization of commands based on individual minions.

.. conf_master:: peer

``peer``
--------

Default: ``{}``

The configuration uses regular expressions to match minions and then a list
of regular expressions to match functions. The following will allow the
minion authenticated as foo.example.com to execute functions from the test
and pkg modules.

.. code-block:: yaml

    peer:
      foo\.example\.com:
          - test\..*
          - pkg\..*

This will allow all minions to execute all commands:

.. code-block:: yaml

    peer:
      .*:
          - .*

This is not recommended, since it would allow anyone who gets root on any
single minion to instantly have root on all of the minions!

It is also possible to limit target hosts with the :term:`Compound Matcher`.
You can achieve this by adding another layer in between the source and the
allowed functions:

.. code-block:: yaml

    peer:
      '.*\.example\.com':
        - 'G@role:db':
          - test\..*
          - pkg\..*

.. note::

    Notice that the source hosts are matched by a regular expression
    on their minion ID, while target hosts can be matched by any of
    the :ref:`available matchers <targeting-compound>`.

    Note that globbing and regex matching on pillar values is not supported. You can only match exact values.

.. conf_master:: peer_run

``peer_run``
------------

Default: ``{}``

The peer_run option is used to open up runners on the master to access from the
minions. The peer_run configuration matches the format of the peer
configuration.

The following example would allow foo.example.com to execute the manage.up
runner:


.. code-block:: yaml

    peer_run:
      foo.example.com:
          - manage.up


.. _master-logging-settings:

Master Logging Settings
=======================

.. conf_master:: log_file

``log_file``
------------

Default: ``/var/log/salt/master``

The master log can be sent to a regular file, local path name, or network
location. See also :conf_log:`log_file`.

Examples:

.. code-block:: yaml

    log_file: /var/log/salt/master

.. code-block:: yaml

    log_file: file:///dev/log

.. code-block:: yaml

    log_file: udp://loghost:10514


.. conf_master:: log_level

``log_level``
-------------

Default: ``warning``

The level of messages to send to the console. See also :conf_log:`log_level`.

.. code-block:: yaml

    log_level: warning

Any log level below the `info` level is INSECURE and may log sensitive data. This currently includes:
#. profile
#. debug
#. trace
#. garbage
#. all

.. conf_master:: log_level_logfile

``log_level_logfile``
---------------------

Default: ``warning``

The level of messages to send to the log file. See also
:conf_log:`log_level_logfile`. When it is not set explicitly
it will inherit the level set by :conf_log:`log_level` option.

.. code-block:: yaml

    log_level_logfile: warning

Any log level below the `info` level is INSECURE and may log sensitive data. This currently includes:
#. profile
#. debug
#. trace
#. garbage
#. all

.. conf_master:: log_datefmt

``log_datefmt``
---------------

Default: ``%H:%M:%S``

The date and time format used in console log messages. See also
:conf_log:`log_datefmt`.

.. code-block:: yaml

    log_datefmt: '%H:%M:%S'

.. conf_master:: log_datefmt_logfile

``log_datefmt_logfile``
-----------------------

Default: ``%Y-%m-%d %H:%M:%S``

The date and time format used in log file messages. See also
:conf_log:`log_datefmt_logfile`.

.. code-block:: yaml

    log_datefmt_logfile: '%Y-%m-%d %H:%M:%S'

.. conf_master:: log_fmt_console

``log_fmt_console``
-------------------

Default: ``[%(levelname)-8s] %(message)s``

The format of the console logging messages. See also
:conf_log:`log_fmt_console`.

.. note::
    Log colors are enabled in ``log_fmt_console`` rather than the
    :conf_master:`color` config since the logging system is loaded before the
    master config.

    Console log colors are specified by these additional formatters:

    %(colorlevel)s
    %(colorname)s
    %(colorprocess)s
    %(colormsg)s

    Since it is desirable to include the surrounding brackets, '[' and ']', in
    the coloring of the messages, these color formatters also include padding
    as well.  Color LogRecord attributes are only available for console
    logging.

.. code-block:: yaml

    log_fmt_console: '%(colorlevel)s %(colormsg)s'
    log_fmt_console: '[%(levelname)-8s] %(message)s'

.. conf_master:: log_fmt_logfile

``log_fmt_logfile``
-------------------

Default: ``%(asctime)s,%(msecs)03d [%(name)-17s][%(levelname)-8s] %(message)s``

The format of the log file logging messages. See also
:conf_log:`log_fmt_logfile`.

.. code-block:: yaml

    log_fmt_logfile: '%(asctime)s,%(msecs)03d [%(name)-17s][%(levelname)-8s] %(message)s'

.. conf_master:: log_granular_levels

``log_granular_levels``
-----------------------

Default: ``{}``

This can be used to control logging levels more specifically. See also
:conf_log:`log_granular_levels`.


.. conf_master:: log_rotate_max_bytes

``log_rotate_max_bytes``
------------------------

Default:  ``0``

The maximum number of bytes a single log file may contain before it is rotated.
A value of 0 disables this feature. Currently only supported on Windows. On
other platforms, use an external tool such as 'logrotate' to manage log files.
:conf_log:`log_rotate_max_bytes`


.. conf_master:: log_rotate_backup_count

``log_rotate_backup_count``
---------------------------

Default:  ``0``

The number of backup files to keep when rotating log files. Only used if
:conf_master:`log_rotate_max_bytes` is greater than 0. Currently only supported
on Windows. On other platforms, use an external tool such as 'logrotate' to
manage log files.
:conf_log:`log_rotate_backup_count`


.. _node-groups:

Node Groups
===========

.. conf_master:: nodegroups

``nodegroups``
--------------

Default: ``{}``

Node groups allow for logical groupings of minion nodes.
A group consists of a group name and a compound target.

.. code-block:: yaml

    nodegroups:
      group1: '[email protected],bar.domain.com,baz.domain.com or bl*.domain.com'
      group2: 'G@os:Debian and foo.domain.com'
      group3: 'G@os:Debian and N@group1'
      group4:
        - 'G@foo:bar'
        - 'or'
        - 'G@foo:baz'

More information on using nodegroups can be found :ref:`here <targeting-nodegroups>`.


.. _range-cluster-settings:

Range Cluster Settings
======================

.. conf_master:: range_server

``range_server``
----------------

Default: ``'range:80'``

The range server (and optional port) that serves your cluster information
https://github.com/ytoolshed/range/wiki/%22yamlfile%22-module-file-spec

.. code-block:: yaml

    range_server: range:80


.. _include-configuration:

Include Configuration
=====================

Configuration can be loaded from multiple files. The order in which this is
done is:

1. The master config file itself

2. The files matching the glob in :conf_master:`default_include`

3. The files matching the glob in :conf_master:`include` (if defined)

Each successive step overrides any values defined in the previous steps.
Therefore, any config options defined in one of the
:conf_master:`default_include` files would override the same value in the
master config file, and any options defined in :conf_master:`include` would
override both.

.. conf_master:: default_include

``default_include``
-------------------

Default: ``master.d/*.conf``

The master can include configuration from other files. Per default the
master will automatically include all config files from ``master.d/*.conf``
where ``master.d`` is relative to the directory of the master configuration
file.

.. note::

    Salt creates files in the ``master.d`` directory for its own use. These
    files are prefixed with an underscore. A common example of this is the
    ``_schedule.conf`` file.

.. conf_master:: include

``include``
-----------

Default: ``not defined``

The master can include configuration from other files. To enable this,
pass a list of paths to this option. The paths can be either relative or
absolute; if relative, they are considered to be relative to the directory
the main minion configuration file lives in. Paths can make use of
shell-style globbing. If no files are matched by a path passed to this
option then the master will log a warning message.

.. code-block:: yaml

    # Include files from a master.d directory in the same
    # directory as the master config file
    include: master.d/*

    # Include a single extra file into the configuration
    include: /etc/roles/webserver

    # Include several files and the master.d directory
    include:
      - extra_config
      - master.d/*
      - /etc/roles/webserver


Keepalive Settings
==================

.. conf_master:: tcp_keepalive

``tcp_keepalive``
-----------------

Default: ``True``

The tcp keepalive interval to set on TCP ports. This setting can be used to tune Salt
connectivity issues in messy network environments with misbehaving firewalls.

.. code-block:: yaml

    tcp_keepalive: True

.. conf_master:: tcp_keepalive_cnt

``tcp_keepalive_cnt``
---------------------

Default: ``-1``

Sets the ZeroMQ TCP keepalive count. May be used to tune issues with minion disconnects.

.. code-block:: yaml

    tcp_keepalive_cnt: -1

.. conf_master:: tcp_keepalive_idle

``tcp_keepalive_idle``
----------------------

Default: ``300``

Sets ZeroMQ TCP keepalive idle. May be used to tune issues with minion disconnects.

.. code-block:: yaml

    tcp_keepalive_idle: 300

.. conf_master:: tcp_keepalive_intvl

``tcp_keepalive_intvl``
-----------------------

Default: ``-1``

Sets ZeroMQ TCP keepalive interval. May be used to tune issues with minion disconnects.

.. code-block:: yaml

    tcp_keepalive_intvl': -1


.. _winrepo-master-config-opts:

Windows Software Repo Settings
==============================

.. conf_master:: winrepo_provider

``winrepo_provider``
--------------------

.. versionadded:: 2015.8.0

Specify the provider to be used for winrepo. Must be either ``pygit2`` or
``gitpython``. If unset, then both will be tried in that same order, and the
first one with a compatible version installed will be the provider that is
used.

.. code-block:: yaml

    winrepo_provider: gitpython

.. conf_master:: winrepo_dir
.. conf_master:: win_repo

``winrepo_dir``
---------------

.. versionchanged:: 2015.8.0

    Renamed from ``win_repo`` to ``winrepo_dir``.

Default: ``/srv/salt/win/repo``

Location on the master where the :conf_master:`winrepo_remotes` are checked out
for pre-2015.8.0 minions. 2015.8.0 and later minions use
:conf_master:`winrepo_remotes_ng <winrepo_remotes_ng>` instead.

.. code-block:: yaml

    winrepo_dir: /srv/salt/win/repo

.. conf_master:: winrepo_dir_ng

``winrepo_dir_ng``
------------------

.. versionadded:: 2015.8.0
    A new :ref:`ng <windows-package-manager>` repo was added.

Default: ``/srv/salt/win/repo-ng``

Location on the master where the :conf_master:`winrepo_remotes_ng` are checked
out for 2015.8.0 and later minions.

.. code-block:: yaml

    winrepo_dir_ng: /srv/salt/win/repo-ng

.. conf_master:: winrepo_cachefile
.. conf_master:: win_repo_mastercachefile

``winrepo_cachefile``
---------------------

.. versionchanged:: 2015.8.0

    Renamed from ``win_repo_mastercachefile`` to ``winrepo_cachefile``

.. note::

    2015.8.0 and later minions do not use this setting since the cachefile
    is now generated by the minion.

Default: ``winrepo.p``

Path relative to :conf_master:`winrepo_dir` where the winrepo cache should be
created.

.. code-block:: yaml

    winrepo_cachefile: winrepo.p

.. conf_master:: winrepo_remotes
.. conf_master:: win_gitrepos

``winrepo_remotes``
-------------------

.. versionchanged:: 2015.8.0

    Renamed from ``win_gitrepos`` to ``winrepo_remotes``.

Default: ``['https://github.com/saltstack/salt-winrepo.git']``

List of git repositories to checkout and include in the winrepo for
pre-2015.8.0 minions. 2015.8.0 and later minions use
:conf_master:`winrepo_remotes_ng <winrepo_remotes_ng>` instead.

.. code-block:: yaml

    winrepo_remotes:
      - https://github.com/saltstack/salt-winrepo.git

To specify a specific revision of the repository, prepend a commit ID to the
URL of the repository:

.. code-block:: yaml

    winrepo_remotes:
      - '<commit_id> https://github.com/saltstack/salt-winrepo.git'

Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
ID is useful in that it allows one to revert back to a previous version in the
event that an error is introduced in the latest revision of the repo.

.. conf_master:: winrepo_remotes_ng

``winrepo_remotes_ng``
----------------------

.. versionadded:: 2015.8.0
    A new :ref:`ng <windows-package-manager>` repo was added.

Default: ``['https://github.com/saltstack/salt-winrepo-ng.git']``

List of git repositories to checkout and include in the winrepo for
2015.8.0 and later minions.

.. code-block:: yaml

    winrepo_remotes_ng:
      - https://github.com/saltstack/salt-winrepo-ng.git

To specify a specific revision of the repository, prepend a commit ID to the
URL of the repository:

.. code-block:: yaml

    winrepo_remotes_ng:
      - '<commit_id> https://github.com/saltstack/salt-winrepo-ng.git'

Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
ID is useful in that it allows one to revert back to a previous version in the
event that an error is introduced in the latest revision of the repo.

.. conf_master:: winrepo_branch

``winrepo_branch``
------------------

.. versionadded:: 2015.8.0

Default: ``master``

If the branch is omitted from a winrepo remote, then this branch will be
used instead. For example, in the configuration below, the first two remotes
would use the ``winrepo`` branch/tag, while the third would use the ``foo``
branch/tag.

.. code-block:: yaml

    winrepo_branch: winrepo

    winrepo_remotes:
      - https://mygitserver/winrepo1.git
      - https://mygitserver/winrepo2.git:
      - foo https://mygitserver/winrepo3.git

.. conf_master:: winrepo_ssl_verify

``winrepo_ssl_verify``
----------------------

.. versionadded:: 2015.8.0
.. versionchanged:: 2016.11.0

Default: ``False``

Specifies whether or not to ignore SSL certificate errors when contacting the
remote repository. The  ``False`` setting is useful if you're using a
git repo that uses a self-signed certificate. However, keep in mind that
setting this to anything other ``True`` is a considered insecure, and using an
SSH-based transport (if available) may be a better option.

In the 2016.11.0 release, the default config value changed from ``False`` to
``True``.

.. code-block:: yaml

    winrepo_ssl_verify: True

Winrepo Authentication Options
------------------------------

These parameters only currently apply to the ``pygit2``
:conf_master:`winrepo_provider`. Authentication works the same as it does in
gitfs, as outlined in the :ref:`GitFS Walkthrough <gitfs-authentication>`,
though the global configuration options are named differently to reflect that
they are for winrepo instead of gitfs.

.. conf_master:: winrepo_user

``winrepo_user``
****************

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`winrepo_password`, is used to authenticate to HTTPS
remotes.

.. code-block:: yaml

    winrepo_user: git

.. conf_master:: winrepo_password

``winrepo_password``
********************

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`winrepo_user`, is used to authenticate to HTTPS
remotes. This parameter is not required if the repository does not use
authentication.

.. code-block:: yaml

    winrepo_password: mypassword

.. conf_master:: winrepo_insecure_auth

``winrepo_insecure_auth``
*************************

.. versionadded:: 2015.8.0

Default: ``False``

By default, Salt will not authenticate to an HTTP (non-HTTPS) remote. This
parameter enables authentication over HTTP. **Enable this at your own risk.**

.. code-block:: yaml

    winrepo_insecure_auth: True

.. conf_master:: winrepo_pubkey

``winrepo_pubkey``
******************

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`winrepo_privkey` (and optionally
:conf_master:`winrepo_passphrase`), is used to authenticate to SSH remotes.

.. code-block:: yaml

    winrepo_pubkey: /path/to/key.pub

.. conf_master:: winrepo_privkey

``winrepo_privkey``
*******************

.. versionadded:: 2015.8.0

Default: ``''``

Along with :conf_master:`winrepo_pubkey` (and optionally
:conf_master:`winrepo_passphrase`), is used to authenticate to SSH remotes.

.. code-block:: yaml

    winrepo_privkey: /path/to/key

.. conf_master:: winrepo_passphrase

``winrepo_passphrase``
**********************

.. versionadded:: 2015.8.0

Default: ``''``

This parameter is optional, required only when the SSH key being used to
authenticate is protected by a passphrase.

.. code-block:: yaml

    winrepo_passphrase: mypassphrase

.. conf_master:: winrepo_refspecs

``winrepo_refspecs``
********************

.. versionadded:: 2017.7.0

Default: ``['+refs/heads/*:refs/remotes/origin/*', '+refs/tags/*:refs/tags/*']``

When fetching from remote repositories, by default Salt will fetch branches and
tags. This parameter can be used to override the default and specify
alternate refspecs to be fetched. This parameter works similarly to its
:ref:`GitFS counterpart <gitfs-custom-refspecs>`, in that it can be
configured both globally and for individual remotes.

.. code-block:: yaml

    winrepo_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'
      - '+refs/pull/*/head:refs/remotes/origin/pr/*'
      - '+refs/pull/*/merge:refs/remotes/origin/merge/*'


.. _configure-master-on-windows:

Configure Master on Windows
===========================

The master on Windows requires no additional configuration. You can modify the
master configuration by creating/editing the master config file located at
``c:\salt\conf\master``. The same configuration options available on Linux are
available in Windows, as long as they apply. For example, SSH options wouldn't
apply in Windows. The main differences are the file paths. If you are familiar
with common salt paths, the following table may be useful:

=============  =========  =================
linux Paths               Windows Paths
=============  =========  =================
``/etc/salt``  ``<--->``  ``c:\salt\conf``
``/``          ``<--->``  ``c:\salt``
=============  =========  =================

So, for example, the master config file in Linux is ``/etc/salt/master``. In
Windows the master config file is ``c:\salt\conf\master``. The Linux path
``/etc/salt`` becomes ``c:\salt\conf`` in Windows.

Common File Locations
---------------------

======================================  =============================================
Linux Paths                             Windows Paths
======================================  =============================================
``conf_file: /etc/salt/master``         ``conf_file: c:\salt\conf\master``
``log_file: /var/log/salt/master``      ``log_file: c:\salt\var\log\salt\master``
``pidfile: /var/run/salt-master.pid``   ``pidfile: c:\salt\var\run\salt-master.pid``
======================================  =============================================

Common Directories
------------------

======================================================  ============================================
Linux Paths                                             Windows Paths
======================================================  ============================================
``cachedir: /var/cache/salt/master``                    ``cachedir: c:\salt\var\cache\salt\master``
``extension_modules: /var/cache/salt/master/extmods``   ``c:\salt\var\cache\salt\master\extmods``
``pki_dir: /etc/salt/pki/master``                       ``pki_dir: c:\salt\conf\pki\master``
``root_dir: /``                                         ``root_dir: c:\salt``
``sock_dir: /var/run/salt/master``                      ``sock_dir: c:\salt\var\run\salt\master``
======================================================  ============================================

Roots
-----

**file_roots**

==================  =========================
Linux Paths         Windows Paths
==================  =========================
``/srv/salt``       ``c:\salt\srv\salt``
``/srv/spm/salt``   ``c:\salt\srv\spm\salt``
==================  =========================

**pillar_roots**

====================  ===========================
Linux Paths           Windows Paths
====================  ===========================
``/srv/pillar``       ``c:\salt\srv\pillar``
``/srv/spm/pillar``   ``c:\salt\srv\spm\pillar``
====================  ===========================

Win Repo Settings
-----------------

==========================================  =================================================
Linux Paths                                 Windows Paths
==========================================  =================================================
``winrepo_dir: /srv/salt/win/repo``         ``winrepo_dir: c:\salt\srv\salt\win\repo``
``winrepo_dir_ng: /srv/salt/win/repo-ng``   ``winrepo_dir_ng: c:\salt\srv\salt\win\repo-ng``
==========================================  =================================================

---

### Doc Ref Configuration Minion (`doc/ref/configuration/minion.rst`)

.. _configuration-salt-minion:

===========================
Configuring the Salt Minion
===========================

The Salt system is amazingly simple and easy to configure. The two components
of the Salt system each have a respective configuration file. The
:command:`salt-master` is configured via the master configuration file, and the
:command:`salt-minion` is configured via the minion configuration file.

.. seealso::
    :ref:`example minion configuration file <configuration-examples-minion>`

The Salt Minion configuration is very simple. Typically, the only value that
needs to be set is the master value so the minion knows where to locate its master.

By default, the salt-minion configuration will be in :file:`/etc/salt/minion`.
A notable exception is FreeBSD, where the configuration will be in
:file:`/usr/local/etc/salt/minion`.



Minion Primary Configuration
============================

.. conf_minion:: master

``master``
----------

Default: ``salt``

The hostname or IP address of the master. See :conf_minion:`ipv6` for IPv6
connections to the master.

Default: ``salt``

.. code-block:: yaml

    master: salt

master:port Syntax
~~~~~~~~~~~~~~~~~~

.. versionadded:: 2015.8.0

The ``master`` config option can also be set to use the master's IP in
conjunction with a port number by default.

.. code-block:: yaml

    master: localhost:1234

For IPv6 formatting with a port, remember to add brackets around the IP address
before adding the port and enclose the line in single quotes to make it a string:

.. code-block:: yaml

    master: '[2001:db8:85a3:8d3:1319:8a2e:370:7348]:1234'

.. note::

    If a port is specified in the ``master`` as well as :conf_minion:`master_port`,
    the ``master_port`` setting will be overridden by the ``master`` configuration.

List of Masters Syntax
~~~~~~~~~~~~~~~~~~~~~~

The option can also be set to a list of masters, enabling
:ref:`multi-master <tutorial-multi-master>` mode.

.. code-block:: yaml

    master:
      - address1
      - address2

.. versionchanged:: 2014.7.0

    The master can be dynamically configured. The :conf_minion:`master` value
    can be set to an module function which will be executed and will assume
    that the returning value is the ip or hostname of the desired master. If a
    function is being specified, then the :conf_minion:`master_type` option
    must be set to ``func``, to tell the minion that the value is a function to
    be run and not a fully-qualified domain name.

    .. code-block:: yaml

        master: module.function
        master_type: func

    In addition, instead of using multi-master mode, the minion can be
    configured to use the list of master addresses as a failover list, trying
    the first address, then the second, etc. until the minion successfully
    connects. To enable this behavior, set :conf_minion:`master_type` to
    ``failover``:

    .. code-block:: yaml

        master:
          - address1
          - address2
        master_type: failover

.. conf_minion:: color

``color``
---------

Default: ``True``

By default output is colored. To disable colored output, set the color value to
``False``.

.. conf_minion:: ipv6

``ipv6``
--------

Default: ``None``

Whether the master should be connected over IPv6. By default salt minion
will try to automatically detect IPv6 connectivity to master.

When set to ``True``, Salt also uses the IPv6 loopback address (``::1``) for
internal IPC connections instead of ``127.0.0.1``. On Windows, this is
required because Windows does not permit binding an ``AF_INET6`` socket to an
IPv4 address.

.. code-block:: yaml

    ipv6: True

.. conf_minion:: master_uri_format

``master_uri_format``
---------------------

.. versionadded:: 2015.8.0

Specify the format in which the master address will be evaluated. Valid options
are ``default`` or ``ip_only``. If ``ip_only`` is specified, then the master
address will not be split into IP and PORT, so be sure that only an IP (or domain
name) is set in the :conf_minion:`master` configuration setting.

.. code-block:: yaml

    master_uri_format: ip_only

.. conf_minion:: master_tops_first

``master_tops_first``
---------------------

.. versionadded:: 2018.3.0

Default: ``False``

SLS targets defined using the :ref:`Master Tops <master-tops-system>` system
are normally executed *after* any matches defined in the :ref:`Top File
<states-top>`. Set this option to ``True`` to have the minion execute the
:ref:`Master Tops <master-tops-system>` states first.

.. code-block:: yaml

    master_tops_first: True

.. conf_minion:: master_type

``master_type``
---------------

.. versionadded:: 2014.7.0

Default: ``str``

The type of the :conf_minion:`master` variable. Can be ``str``, ``failover``,
``func`` or ``disable``.

.. code-block:: yaml

    master_type: str

If this option is ``str`` (default), multiple hot masters are configured.
Minions can connect to multiple masters simultaneously (all master are "hot").

.. code-block:: yaml

    master_type: failover

If this option is set to ``failover``, :conf_minion:`master` must be a list of
master addresses. The minion will then try each master in the order specified
in the list until it successfully connects.  :conf_minion:`master_alive_interval`
must also be set, this determines how often the minion will verify the presence
of the master.

.. code-block:: yaml

    master_type: func

If the master needs to be dynamically assigned by executing a function instead
of reading in the static master value, set this to ``func``. This can be used
to manage the minion's master setting from an execution module. By simply
changing the algorithm in the module to return a new master ip/fqdn, restart
the minion and it will connect to the new master.

As of version 2016.11.0 this option can be set to ``disable`` and the minion
will never attempt to talk to the master. This is useful for running a
masterless minion daemon.

.. code-block:: yaml

    master_type: disable

.. conf_minion:: max_event_size

``max_event_size``
------------------

.. versionadded:: 2014.7.0

Default: ``1048576``

Passing very large events can cause the minion to consume large amounts of
memory. This value tunes the maximum size of a message allowed onto the
minion event bus. The value is expressed in bytes.

.. code-block:: yaml

    max_event_size: 1048576

.. conf_minion:: enable_legacy_startup_events

``enable_legacy_startup_events``
--------------------------------

.. versionadded:: 2019.2.0

Default: ``True``

When a minion starts up it sends a notification on the event bus with a tag
that looks like this: ``salt/minion/<minion_id>/start``. For historical reasons
the minion also sends a similar event with an event tag like this:
``minion_start``. This duplication can cause a lot of clutter on the event bus
when there are many minions. Set ``enable_legacy_startup_events: False`` in the
minion config to ensure only the ``salt/minion/<minion_id>/start`` events are
sent. Beginning with the ``3001`` Salt release this option will default to
``False``.

.. code-block:: yaml

    enable_legacy_startup_events: True

.. conf_minion:: master_failback

``master_failback``
-------------------

.. versionadded:: 2016.3.0

Default: ``False``

If the minion is in multi-master mode and the :conf_minion`master_type`
configuration option is set to ``failover``, this setting can be set to ``True``
to force the minion to fail back to the first master in the list if the first
master is back online.

.. code-block:: yaml

    master_failback: False

.. conf_minion:: master_failback_interval

``master_failback_interval``
----------------------------

.. versionadded:: 2016.3.0

Default: ``0``

If the minion is in multi-master mode, the :conf_minion`master_type` configuration
is set to ``failover``, and the ``master_failback`` option is enabled, the master
failback interval can be set to ping the top master with this interval, in seconds.

.. code-block:: yaml

    master_failback_interval: 0

.. conf_minion:: master_alive_interval

``master_alive_interval``
-------------------------

Default: ``0``

Configures how often, in seconds, the minion will verify that the current
master is alive and responding.  The minion will try to establish a connection
to the next master in the list if it finds the existing one is dead. This
setting can also be used to detect master DNS record changes when a minion has
been disconnected.

.. code-block:: yaml

    master_alive_interval: 30

.. conf_minion:: master_shuffle

``master_shuffle``
------------------

.. versionadded:: 2014.7.0
.. deprecated:: 2019.2.0

Default: ``False``

.. warning::

    This option has been deprecated in Salt ``2019.2.0``. Please use
    :conf_minion:`random_master` instead.

.. code-block:: yaml

    master_shuffle: True

.. conf_minion:: random_master

``random_master``
-----------------

.. versionadded:: 2014.7.0
.. versionchanged:: 2019.2.0
    The :conf_minion:`master_failback` option can be used in conjunction with
    ``random_master`` to force the minion to fail back to the first master in the
    list if the first master is back online. Note that :conf_minion:`master_type`
    must be set to ``failover`` in order for the ``master_failback`` setting to
    work.

Default: ``False``

If :conf_minion:`master` is a list of addresses, shuffle them before trying to
connect to distribute the minions over all available masters. This uses Python's
:func:`random.shuffle ` method.

If multiple masters are specified in the 'master' setting as a list, the default
behavior is to always try to connect to them in the order they are listed. If
``random_master`` is set to True, the order will be randomized instead upon Minion
startup. This can be helpful in distributing the load of many minions executing
``salt-call`` requests, for example, from a cron job. If only one master is listed,
this setting is ignored and a warning is logged.

.. code-block:: yaml

    random_master: True

.. note::

    When the ``failover``, ``master_failback``, and ``random_master`` options are
    used together, only the "secondary masters" will be shuffled. The first master
    in the list is ignored in the :func:`random.shuffle `
    call. See :conf_minion:`master_failback` for more information.

.. conf_minion:: retry_dns

``retry_dns``
-------------

Default: ``30``

Set the number of seconds to wait before attempting to resolve
the master hostname if name resolution fails. Defaults to 30 seconds.
Set to zero if the minion should shutdown and not retry.

.. code-block:: yaml

    retry_dns: 30

.. conf_minion:: retry_dns_count

``retry_dns_count``
-------------------

.. versionadded:: 2018.3.4

Default: ``None``

Set the number of attempts to perform when resolving
the master hostname if name resolution fails.
By default the minion will retry indefinitely.

.. code-block:: yaml

    retry_dns_count: 3

.. conf_minion:: master_port

``master_port``
---------------

Default: ``4506``

The port of the master ret server, this needs to coincide with the ret_port
option on the Salt master.

.. code-block:: yaml

    master_port: 4506

.. conf_minion:: publish_port

``publish_port``
----------------

Default: ``4505``

The port of the master publish server, this needs to coincide with the publish_port
option on the Salt master.

.. code-block:: yaml

    publish_port: 4505

.. conf_minion:: source_interface_name

``source_interface_name``
-------------------------

.. versionadded:: 2018.3.0

The name of the interface to use when establishing the connection to the Master.

.. note::

    If multiple IP addresses are configured on the named interface,
    the first one will be selected. In that case, for a better selection,
    consider using the :conf_minion:`source_address` option.

.. note::

    To use an IPv6 address from the named interface, make sure the option
    :conf_minion:`ipv6` is enabled, i.e., ``ipv6: true``.

.. note::

    If the interface is down, it will avoid using it, and the Minion
    will bind to ``0.0.0.0`` (all interfaces).

.. warning::

    This option requires modern version of the underlying libraries used by
    the selected transport:

    - ``zeromq`` requires ``pyzmq`` >= 16.0.1 and ``libzmq`` >= 4.1.6
    - ``tcp`` requires ``tornado`` >= 4.5

Configuration example:

.. code-block:: yaml

    source_interface_name: bond0.1234

.. conf_minion:: source_address

``source_address``
------------------

.. versionadded:: 2018.3.0

The source IP address or the domain name to be used when connecting the Minion
to the Master.
See :conf_minion:`ipv6` for IPv6 connections to the Master.

.. warning::

    This option requires modern version of the underlying libraries used by
    the selected transport:

    - ``zeromq`` requires ``pyzmq`` >= 16.0.1 and ``libzmq`` >= 4.1.6
    - ``tcp`` requires ``tornado`` >= 4.5

Configuration example:

.. code-block:: yaml

    source_address: if-bond0-1234.sjc.us-west.internal

.. conf_minion:: source_ret_port

``source_ret_port``
-------------------

.. versionadded:: 2018.3.0

The source port to be used when connecting the Minion to the Master ret server.

.. warning::

    This option requires modern version of the underlying libraries used by
    the selected transport:

    - ``zeromq`` requires ``pyzmq`` >= 16.0.1 and ``libzmq`` >= 4.1.6
    - ``tcp`` requires ``tornado`` >= 4.5

Configuration example:

.. code-block:: yaml

    source_ret_port: 49017

.. conf_minion:: source_publish_port

``source_publish_port``
-----------------------

.. versionadded:: 2018.3.0

The source port to be used when connecting the Minion to the Master publish
server.

.. warning::

    This option requires modern version of the underlying libraries used by
    the selected transport:

    - ``zeromq`` requires ``pyzmq`` >= 16.0.1 and ``libzmq`` >= 4.1.6
    - ``tcp`` requires ``tornado`` >= 4.5

Configuration example:

.. code-block:: yaml

    source_publish_port: 49018

.. conf_minion:: user

``user``
--------

Default: ``root``

The user to run the Salt processes

.. code-block:: yaml

    user: root

.. conf_minion:: sudo_user

``sudo_user``
-------------

Default: ``''``

The user to run salt remote execution commands as via sudo. If this option is
enabled then sudo will be used to change the active user executing the remote
command. If enabled the user will need to be allowed access via the sudoers file
for the user that the salt minion is configured to run as. The most common
option would be to use the root user. If this option is set the ``user`` option
should also be set to a non-root user. If migrating from a root minion to a non
root minion the minion cache should be cleared and the minion pki directory will
need to be changed to the ownership of the new user.

.. code-block:: yaml

    sudo_user: root


``pidfile``
-----------

Default: ``/var/run/salt-minion.pid``

The location of the daemon's process ID file

.. code-block:: yaml

    pidfile: /var/run/salt-minion.pid

.. conf_minion:: root_dir

``root_dir``
------------

Default: ``/``

This directory is prepended to the following options: :conf_minion:`pki_dir`,
:conf_minion:`cachedir`, :conf_minion:`log_file`, :conf_minion:`sock_dir`, and
:conf_minion:`pidfile`.

.. code-block:: yaml

    root_dir: /

.. conf_minion:: conf_file

``conf_file``
-------------

Default: ``/etc/salt/minion``

The path to the minion's configuration file.

.. code-block:: yaml

    conf_file: /etc/salt/minion

.. conf_minion:: pki_dir

``pki_dir``
-----------

Default: ``<LIB_STATE_DIR>/pki/minion``

The directory used to store the minion's public and private keys.

``<LIB_STATE_DIR>`` is the pre-configured variable state directory set during
installation via ``--salt-lib-state-dir``. It defaults to ``/etc/salt``. Systems
following the Filesystem Hierarchy Standard (FHS) might set it to
``/var/lib/salt``.

.. code-block:: yaml

    pki_dir: /etc/salt/pki/minion

.. conf_minion:: id

``id``
------

Default: the system's hostname

.. seealso:: :ref:`Salt Walkthrough <minion-id-generation>`

    The :strong:`Setting up a Salt Minion` section contains detailed
    information on how the hostname is determined.

Explicitly declare the id for this minion to use. Since Salt uses detached ids
it is possible to run multiple minions on the same machine but with different
ids.

.. code-block:: yaml

    id: foo.bar.com

.. conf_minion:: minion_id_caching

``minion_id_caching``
---------------------

.. versionadded:: 0.17.2

Default: ``True``

Caches the minion id to a file when the minion's :conf_minion:`id` is not
statically defined in the minion config. This setting prevents potential
problems when automatic minion id resolution changes, which can cause the
minion to lose connection with the master. To turn off minion id caching,
set this config to ``False``.

For more information, please see `Issue #7558`_ and `Pull Request #8488`_.

.. code-block:: yaml

    minion_id_caching: True

.. _Issue #7558: https://github.com/saltstack/salt/issues/7558
.. _Pull Request #8488: https://github.com/saltstack/salt/pull/8488

.. conf_minion:: append_domain

``append_domain``
-----------------

Default: ``None``

Append a domain to a hostname in the event that it does not exist. This is
useful for systems where ``socket.getfqdn()`` does not actually result in a
FQDN (for instance, Solaris).

.. code-block:: yaml

    append_domain: foo.org

.. conf_minion:: minion_id_remove_domain

``minion_id_remove_domain``
---------------------------

.. versionadded:: 3000

Default: ``False``

Remove a domain when the minion id is generated as a fully qualified domain
name (either by the user provided ``id_function``, or by Salt). This is useful
when the minions shall be named like hostnames. Can be a single domain (to
prevent name clashes), or True, to remove all domains.

Examples:
 - minion_id_remove_domain = foo.org
   - FQDN = king_bob.foo.org --> minion_id = king_bob
   - FQDN = king_bob.bar.org --> minion_id = king_bob.bar.org
 - minion_id_remove_domain = True
   - FQDN = king_bob.foo.org --> minion_id = king_bob
   - FQDN = king_bob.bar.org --> minion_id = king_bob


For more information, please see :issue:`49212` and  :pull:`49378`.

.. code-block:: yaml

    minion_id_remove_domain: foo.org

.. conf_minion:: minion_id_lowercase

``minion_id_lowercase``
-----------------------

Default: ``False``

Convert minion id to lowercase when it is being generated. Helpful when some hosts
get the minion id in uppercase. Cached ids will remain the same and not converted.

.. code-block:: yaml

    minion_id_lowercase: True

.. conf_minion:: cachedir

``cachedir``
------------

Default: ``/var/cache/salt/minion``

The location for minion cache data.

This directory may contain sensitive data and should be protected accordingly.

.. code-block:: yaml

    cachedir: /var/cache/salt/minion

.. conf_minion:: color_theme

``color_theme``
---------------

Default: ``""``

Specifies a path to the color theme to use for colored command line output.

.. code-block:: yaml

    color_theme: /etc/salt/color_theme

.. conf_minion:: append_minionid_config_dirs

``append_minionid_config_dirs``
-------------------------------

Default: ``[]`` (the empty list) for regular minions, ``['cachedir']`` for proxy minions.

Append minion_id to these configuration directories.  Helps with multiple proxies
and minions running on the same machine. Allowed elements in the list:
``pki_dir``, ``cachedir``, ``extension_modules``.
Normally not needed unless running several proxies and/or minions on the same machine.

.. code-block:: yaml

    append_minionid_config_dirs:
      - pki_dir
      - cachedir


``verify_env``
--------------

Default: ``True``

Verify and set permissions on configuration directories at startup.

.. code-block:: yaml

    verify_env: True

.. note::

    When set to ``True`` the verify_env option requires WRITE access to the
    configuration directory (/etc/salt/). In certain situations such as
    mounting /etc/salt/ as read-only for templating this will create a stack
    trace when :py:func:`state.apply <salt.modules.state.apply_>` is called.

.. conf_minion:: cache_jobs

``cache_jobs``
--------------

Default: ``False``

The minion can locally cache the return data from jobs sent to it, this can be
a good way to keep track of the minion side of the jobs the minion has
executed. By default this feature is disabled, to enable set cache_jobs to
``True``.

.. code-block:: yaml

    cache_jobs: False

.. conf_minion:: grains

``grains``
----------

Default: (empty)

.. seealso::
    :ref:`static-custom-grains`

Statically assigns grains to the minion.

.. code-block:: yaml

    grains:
      roles:
        - webserver
        - memcache
      deployment: datacenter4
      cabinet: 13
      cab_u: 14-15

.. conf_minion:: grains_blacklist

``grains_blacklist``
--------------------

Default: ``[]``

Each grains key will be compared against each of the expressions in this list.
Any keys which match will be filtered from the grains. Exact matches, glob
matches, and regular expressions are supported.

.. note::
    Some states and execution modules depend on grains. Filtering may cause
    them to be unavailable or run unreliably.

.. versionadded:: 3000

.. code-block:: yaml

    grains_blacklist:
      - cpu_flags
      - zmq*
      - ipv[46]

.. conf_minion:: grains_cache

``grains_cache``
----------------

Default: ``False``

The minion can locally cache grain data instead of refreshing the data
each time the grain is referenced. By default this feature is disabled,
to enable set ``grains_cache`` to ``True``.

.. code-block:: yaml

    grains_cache: False

.. conf_minion:: grains_cache_expiration

``grains_cache_expiration``
---------------------------

Default: ``300``

Grains cache expiration, in seconds. If the cache file is older than this number
of seconds then the grains cache will be dumped and fully re-populated with
fresh data. Defaults to 5 minutes. Will have no effect if
:conf_minion:`grains_cache` is not enabled.

.. code-block:: yaml

    grains_cache_expiration: 300

.. conf_minion:: grains_deep_merge

``grains_deep_merge``
---------------------

.. versionadded:: 2016.3.0

Default: ``False``

The grains can be merged, instead of overridden, using this option.
This allows custom grains to defined different subvalues of a dictionary
grain. By default this feature is disabled, to enable set grains_deep_merge
to ``True``.

.. code-block:: yaml

    grains_deep_merge: False

For example, with these custom grains functions:

.. code-block:: python

    def custom1_k1():
        return {"custom1": {"k1": "v1"}}


    def custom1_k2():
        return {"custom1": {"k2": "v2"}}

Without ``grains_deep_merge``, the result would be:

.. code-block:: yaml

    custom1:
      k1: v1

With ``grains_deep_merge``, the result will be:

.. code-block:: yaml

    custom1:
      k1: v1
      k2: v2

.. conf_minion:: grains_refresh_every

``grains_refresh_every``
------------------------

Default: ``0``

The ``grains_refresh_every`` setting allows for a minion to periodically
check its grains to see if they have changed and, if so, to inform the master
of the new grains. This operation is moderately expensive, therefore care
should be taken not to set this value too low.

Note: This value is expressed in minutes.

A value of 10 minutes is a reasonable default.

.. code-block:: yaml

    grains_refresh_every: 0

.. conf_minion:: grains_refresh_pre_exec

``grains_refresh_pre_exec``
---------------------------

.. versionadded:: 3005

Default: ``False``

The ``grains_refresh_pre_exec`` setting allows for a minion to check its grains
prior to the execution of any operation to see if they have changed and, if
so, to inform the master of the new grains. This operation is moderately
expensive, therefore care should be taken before enabling this behavior.

.. code-block:: yaml

    grains_refresh_pre_exec: True

.. conf_minion:: metadata_server_grains

``metadata_server_grains``
--------------------------

.. versionadded:: 2017.7.0

Default: ``False``

Set this option to enable gathering of cloud metadata from
``http://169.254.169.254/latest`` for use in grains (see :py:mod:`here
<salt.grains.metadata>` for more information).

.. code-block:: yaml

    metadata_server_grains: True

.. conf_minion:: fibre_channel_grains

``fibre_channel_grains``
------------------------

Default: ``False``

The ``fibre_channel_grains`` setting will enable the ``fc_wwn`` grain for
Fibre Channel WWN's on the minion. Since this grain is expensive, it is
disabled by default.

.. code-block:: yaml

    fibre_channel_grains: True

.. conf_minion:: iscsi_grains

``iscsi_grains``
------------------------

Default: ``False``

The ``iscsi_grains`` setting will enable the ``iscsi_iqn`` grain on the
minion. Since this grain is expensive, it is disabled by default.

.. code-block:: yaml

    iscsi_grains: True

.. conf_minion:: nvme_grains

``nvme_grains``
------------------------

Default: ``False``

The ``nvme_grains`` setting will enable the ``nvme_nqn`` grain on the
minion. Since this grain is expensive, it is disabled by default.

.. code-block:: yaml

    nvme_grains: True

.. conf_minion:: mine_enabled

``mine_enabled``
----------------

.. versionadded:: 2015.8.10

Default: ``True``

Determines whether or not the salt minion should run scheduled mine updates.  If this is set to
False then the mine update function will not get added to the scheduler for the minion.

.. code-block:: yaml

    mine_enabled: True

.. conf_minion:: mine_return_job

``mine_return_job``
-------------------

.. versionadded:: 2015.8.10

Default: ``False``

Determines whether or not scheduled mine updates should be accompanied by a job
return for the job cache.

.. code-block:: yaml

    mine_return_job: False

``mine_functions``
------------------

Default: Empty

Designate which functions should be executed at mine_interval intervals on each minion.
:ref:`See this documentation on the Salt Mine <salt-mine>` for more information.
Note these can be defined in the pillar for a minion as well.

    :ref:`example minion configuration file <configuration-examples-minion>`

.. code-block:: yaml

    mine_functions:
      test.ping: []
      network.ip_addrs:
        interface: eth0
        cidr: '10.0.0.0/8'

.. conf_minion:: mine_interval

``mine_interval``
-----------------

Default: ``60``

The number of minutes between mine updates.

.. code-block:: yaml

    mine_interval: 60

.. conf_minion:: sock_dir

``sock_dir``
------------

Default: ``/var/run/salt/minion``

The directory where Unix sockets will be kept.

.. code-block:: yaml

    sock_dir: /var/run/salt/minion

.. conf_minion:: enable_fqdns_grains

``enable_fqdns_grains``
-----------------------

Default: ``True``

In order to calculate the fqdns grain, all the IP addresses from the minion are
processed with underlying calls to ``socket.gethostbyaddr`` which can take 5 seconds
to be released (after reaching ``socket.timeout``) when there is no fqdn for that IP.
These calls to ``socket.gethostbyaddr`` are processed asynchronously, however, it still
adds 5 seconds every time grains are generated if an IP does not resolve. In Windows
grains are regenerated each time a new process is spawned. Therefore, the default for
Windows is ``False``. In many cases this value does not make sense to include for proxy
minions as it will be FQDN for the host running the proxy minion process, so the default
for proxy minions is ``False```. On macOS, FQDN resolution can be very slow, therefore
the default for macOS is ``False`` as well. All other OSes default to ``True``.
This option was added `here <https://github.com/saltstack/salt/pull/55581>`_.

.. code-block:: yaml

    enable_fqdns_grains: False

.. conf_minion:: enable_gpu_grains

``enable_gpu_grains``
---------------------

Default: ``True``

Enable GPU hardware data for your master. Be aware that the minion can
take a while to start up when lspci and/or dmidecode is used to populate the
grains for the minion, so this can be set to ``False`` if you do not need these
grains.

.. code-block:: yaml

    enable_gpu_grains: False

.. conf_minion:: outputter_dirs

``outputter_dirs``
------------------

Default: ``[]``

A list of additional directories to search for salt outputters in.

.. code-block:: yaml

    outputter_dirs: []

.. conf_minion:: backup_mode

``backup_mode``
---------------

Default: ``''``

Make backups of files replaced by ``file.managed`` and ``file.recurse`` state modules under
:conf_minion:`cachedir` in ``file_backup`` subdirectory preserving original paths.
Refer to :ref:`File State Backups documentation <file-state-backups>` for more details.

.. code-block:: yaml

    backup_mode: minion

.. conf_minion:: acceptance_wait_time

``acceptance_wait_time``
------------------------

Default: ``10``

The number of seconds to wait until attempting to re-authenticate with the
master.

.. code-block:: yaml

    acceptance_wait_time: 10

.. conf_minion:: acceptance_wait_time_max

``acceptance_wait_time_max``
----------------------------

Default: ``0``

The maximum number of seconds to wait until attempting to re-authenticate
with the master. If set, the wait will increase by :conf_minion:`acceptance_wait_time`
seconds each iteration.

.. code-block:: yaml

    acceptance_wait_time_max: 0

.. conf_minion:: rejected_retry

``rejected_retry``
------------------

Default: ``False``

If the master denies or rejects the minion's public key, retry instead of
exiting.  These keys will be handled the same as waiting on acceptance.

.. code-block:: yaml

    rejected_retry: False

.. conf_minion:: random_reauth_delay

``random_reauth_delay``
-----------------------

Default: ``10``

When the master key changes, the minion will try to re-auth itself to
receive the new master key. In larger environments this can cause a syn-flood
on the master because all minions try to re-auth immediately. To prevent this
and have a minion wait for a random amount of time, use this optional
parameter. The wait-time will be a random number of seconds between
0 and the defined value.

.. code-block:: yaml

    random_reauth_delay: 60

.. conf_minion:: master_tries

``master_tries``
----------------

.. versionadded:: 2016.3.0

Default: ``1``

The number of attempts to connect to a master before giving up. Set this to
``-1`` for unlimited attempts. This allows for a master to have downtime and the
minion to reconnect to it later when it comes back up. In 'failover' mode, which
is set in the :conf_minion:`master_type` configuration, this value is the number
of attempts for each set of masters. In this mode, it will cycle through the list
of masters for each attempt.

``master_tries`` is different than :conf_minion:`auth_tries` because ``auth_tries``
attempts to retry auth attempts with a single master. ``auth_tries`` is under the
assumption that you can connect to the master but not gain authorization from it.
``master_tries`` will still cycle through all of the masters in a given try, so it
is appropriate if you expect occasional downtime from the master(s).

.. code-block:: yaml

    master_tries: 1

.. conf_minion:: auth_tries

``auth_tries``
--------------

.. versionadded:: 2014.7.0

Default: ``7``

The number of attempts to authenticate to a master before giving up. Or, more
technically, the number of consecutive SaltReqTimeoutErrors that are acceptable
when trying to authenticate to the master.

.. code-block:: yaml

    auth_tries: 7

.. conf_minion:: auth_timeout

``auth_timeout``
----------------

.. versionadded:: 2014.7.0

Default: ``5``

When waiting for a master to accept the minion's public key, salt will
continuously attempt to reconnect until successful. This is the timeout value,
in seconds, for each individual attempt. After this timeout expires, the minion
will wait for :conf_minion:`acceptance_wait_time` seconds before trying again.
Unless your master is under unusually heavy load, this should be left at the
default.

.. note::
    For high latency networks try increasing this value

.. code-block:: yaml

    auth_timeout: 5

.. conf_minion:: auth_safemode

``auth_safemode``
-----------------

.. versionadded:: 2014.7.0

Default: ``False``

If authentication fails due to SaltReqTimeoutError during a ping_interval,
this setting, when set to ``True``, will cause a sub-minion process to
restart.

.. code-block:: yaml

    auth_safemode: False

.. conf_minion:: request_channel_timeout

``request_channel_timeout``
---------------------------

.. versionadded:: 3006.2

Default: ``30``

The default timeout timeout for request channel requests. This setting can be used to tune minions to better handle long running pillar and file client requests.

.. code-block:: yaml

    request_channel_timeout: 30

``request_channel_tries``
-------------------------

.. versionadded:: 3006.2

Default: ``3``

The default number of times the minion will try request channel requests. This
setting can be used to tune minions to better handle long running pillar and
file client requests by retrying them after a timeout happens.

.. code-block:: yaml

    request_channel_tries: 3

.. conf_minion:: ping_interval

``ping_interval``
-----------------

Default: ``0``

Instructs the minion to ping its master(s) every n number of minutes. Used
primarily as a mitigation technique against minion disconnects.

.. code-block:: yaml

    ping_interval: 0

.. conf_minion:: recon_default

``random_startup_delay``
------------------------

Default: ``0``

The maximum bound for an interval in which a minion will randomly sleep upon starting
up prior to attempting to connect to a master. This can be used to splay connection attempts
for cases where many minions starting up at once may place undue load on a master.

For example, setting this to ``5`` will tell a minion to sleep for a value between ``0``
and ``5`` seconds.

.. code-block:: yaml

    random_startup_delay: 5

.. conf_minion:: random_startup_delay

``recon_default``
-----------------

Default: ``1000``

The interval in milliseconds that the socket should wait before trying to
reconnect to the master (1000ms = 1 second).

.. code-block:: yaml

    recon_default: 1000

.. conf_minion:: recon_max

``recon_max``
-------------

Default: ``10000``

The maximum time a socket should wait. Each interval the time to wait is calculated
by doubling the previous time. If recon_max is reached, it starts again at
the recon_default.

Short example:
    - reconnect 1: the socket will wait 'recon_default' milliseconds
    - reconnect 2: 'recon_default' * 2
    - reconnect 3: ('recon_default' * 2) * 2
    - reconnect 4: value from previous interval * 2
    - reconnect 5: value from previous interval * 2
    - reconnect x: if value >= recon_max, it starts again with recon_default

.. code-block:: yaml

    recon_max: 10000

.. conf_minion:: recon_randomize

``recon_randomize``
-------------------

Default: ``True``

Generate a random wait time on minion start. The wait time will be a random value
between recon_default and recon_default + recon_max. Having all minions reconnect
with the same recon_default and recon_max value kind of defeats the purpose of being
able to change these settings. If all minions have the same values and the setup is
quite large (several thousand minions), they will still flood the master. The desired
behavior is to have time-frame within all minions try to reconnect.

.. code-block:: yaml

    recon_randomize: True

.. conf_minion:: loop_interval

``loop_interval``
-----------------

Default: ``1``

The loop_interval sets how long in seconds the minion will wait between
evaluating the scheduler and running cleanup tasks. This defaults to 1
second on the minion scheduler.

.. code-block:: yaml

    loop_interval: 1


.. conf_minion:: pub_ret

``pub_ret``
-----------

Default: True

Some installations choose to start all job returns in a cache or a returner
and forgo sending the results back to a master. In this workflow, jobs
are most often executed with --async from the Salt CLI and then results
are evaluated by examining job caches on the minions or any configured returners.
WARNING: Setting this to False will **disable** returns back to the master.

.. code-block:: yaml

    pub_ret: True

.. conf_minion:: return_retry_timer

``return_retry_timer``
----------------------

Default: ``5``

The default timeout for a minion return attempt.

.. code-block:: yaml

    return_retry_timer: 5


.. conf_minion:: return_retry_timer_max

``return_retry_timer_max``
--------------------------

Default: ``10``

The maximum timeout for a minion return attempt. If non-zero the minion return
retry timeout will be a random int between ``return_retry_timer`` and
``return_retry_timer_max``

.. code-block:: yaml

    return_retry_timer_max: 10

.. conf_minion:: return_retry_tries

``return_retry_tries``
--------------------------

Default: ``3``

The maximum number of retries for a minion return attempt.

.. code-block:: yaml

    return_retry_tries: 3

.. conf_minion:: cache_sreqs

``cache_sreqs``
---------------

Default: ``True``

The connection to the master ret_port is kept open. When set to False, the minion
creates a new connection for every return to the master.

.. code-block:: yaml

    cache_sreqs: True

.. conf_minion:: ipc_mode

``ipc_mode``
------------

Default: ``ipc``

Windows platforms lack POSIX IPC and must rely on slower TCP based inter-
process communications. ``ipc_mode`` is set to ``tcp`` on such systems.

.. code-block:: yaml

    ipc_mode: ipc

.. conf_minion:: ipc_write_buffer

``ipc_write_buffer``
-----------------------

Default: ``0``

The maximum size of a message sent via the IPC transport module can be limited
dynamically or by sharing an integer value lower than the total memory size. When
the value ``dynamic`` is set, salt will use 2.5% of the total memory as
``ipc_write_buffer`` value (rounded to an integer). A value of ``0`` disables
this option.

.. code-block:: yaml

    ipc_write_buffer: 10485760

.. conf_minion:: tcp_pub_port

``tcp_pub_port``
----------------

Default: ``4510``

Publish port used when :conf_minion:`ipc_mode` is set to ``tcp``.

.. code-block:: yaml

    tcp_pub_port: 4510

.. conf_minion:: tcp_pull_port

``tcp_pull_port``
-----------------

Default: ``4511``

Pull port used when :conf_minion:`ipc_mode` is set to ``tcp``.

.. code-block:: yaml

    tcp_pull_port: 4511

.. conf_minion:: transport

``transport``
-------------

Default: ``zeromq``

Changes the underlying transport layer. ZeroMQ is the recommended transport
while additional transport layers are under development. Supported values are
``zeromq`` and ``tcp`` (experimental). This setting has a significant impact
on performance and should not be changed unless you know what you are doing!

.. code-block:: yaml

    transport: zeromq

.. conf_minion:: syndic_finger

``syndic_finger``
-----------------

Default: ``''``

The key fingerprint of the higher-level master for the syndic to verify it is
talking to the intended master.

.. code-block:: yaml

    syndic_finger: 'ab:30:65:2a:d6:9e:20:4f:d8:b2:f3:a7:d4:65:50:10'

.. conf_minion:: http_connect_timeout

``http_connect_timeout``
------------------------

.. versionadded:: 2019.2.0

Default: ``20``

HTTP connection timeout in seconds.
Applied when fetching files using tornado back-end.
Should be greater than overall download time.

.. code-block:: yaml

    http_connect_timeout: 20

.. conf_minion:: http_request_timeout

``http_request_timeout``
------------------------

.. versionadded:: 2015.8.0

Default: ``3600``

HTTP request timeout in seconds.
Applied when fetching files using tornado back-end.
Should be greater than overall download time.

.. code-block:: yaml

    http_request_timeout: 3600

.. conf_minion:: proxy_host

``proxy_host``
--------------

Default: ``''``

The hostname used for HTTP proxy access.

.. code-block:: yaml

    proxy_host: proxy.my-domain

.. conf_minion:: proxy_port

``proxy_port``
--------------

Default: ``0``

The port number used for HTTP proxy access.

.. code-block:: yaml

    proxy_port: 31337

.. conf_minion:: proxy_username

``proxy_username``
------------------

Default: ``''``

The username used for HTTP proxy access.

.. code-block:: yaml

    proxy_username: charon

.. conf_minion:: proxy_password

``proxy_password``
------------------

Default: ``''``

The password used for HTTP proxy access.

.. code-block:: yaml

    proxy_password: obolus

.. conf_minion:: no_proxy

``no_proxy``
------------

.. versionadded:: 2019.2.0

Default: ``[]``

List of hosts to bypass HTTP proxy

.. note::
    This key does nothing unless proxy_host etc is configured, it does not
    support any kind of wildcards.

.. code-block:: yaml

    no_proxy: [ '127.0.0.1', 'foo.tld' ]

``use_yamlloader_old``
------------------------

.. versionadded:: 2019.2.1

Default: ``False``

Use the pre-2019.2 YAML renderer.
Uses legacy YAML rendering to support some legacy inline data structures.
See the :ref:`2019.2.1 release notes <release-2019-2-1>` for more details.

.. code-block:: yaml

    use_yamlloader_old: False

Docker Configuration
====================

.. conf_minion:: docker.update_mine

``docker.update_mine``
----------------------

.. versionadded:: 2017.7.8,2018.3.3
.. versionchanged:: 2019.2.0
    The default value is now ``False``

Default: ``True``

If enabled, when containers are added, removed, stopped, started, etc., the
:ref:`mine <salt-mine>` will be updated with the results of :py:func:`docker.ps
verbose=True all=True host=True <salt.modules.dockermod.ps>`. This mine data is
used by :py:func:`mine.get_docker <salt.modules.mine.get_docker>`. Set this
option to ``False`` to keep Salt from updating the mine with this information.

.. note::
    This option can also be set in Grains or Pillar data, with Grains
    overriding Pillar and the minion config file overriding Grains.

.. note::
    Disabling this will of course keep :py:func:`mine.get_docker
    <salt.modules.mine.get_docker>` from returning any information for a given
    minion.

.. code-block:: yaml

    docker.update_mine: False

.. conf_minion:: docker.compare_container_networks

``docker.compare_container_networks``
-------------------------------------

.. versionadded:: 2018.3.0

Default: ``{'static': ['Aliases', 'Links', 'IPAMConfig'], 'automatic': ['IPAddress', 'Gateway', 'GlobalIPv6Address', 'IPv6Gateway']}``

Specifies which keys are examined by
:py:func:`docker.compare_container_networks
<salt.modules.dockermod.compare_container_networks>`.

.. note::
    This should not need to be modified unless new features added to Docker
    result in new keys added to the network configuration which must be
    compared to determine if two containers have different network configs.
    This config option exists solely as a way to allow users to continue using
    Salt to manage their containers after an API change, without waiting for a
    new Salt release to catch up to the changes in the Docker API.

.. code-block:: yaml

    docker.compare_container_networks:
      static:
        - Aliases
        - Links
        - IPAMConfig
      automatic:
        - IPAddress
        - Gateway
        - GlobalIPv6Address
        - IPv6Gateway

.. conf_minion:: optimization_order

``optimization_order``
----------------------

Default: ``[0, 1, 2]``

In cases where Salt is distributed without .py files, this option determines
the priority of optimization level(s) Salt's module loader should prefer.

.. note::
    This option is only supported on Python 3.5+.

.. code-block:: yaml

    optimization_order:
      - 2
      - 0
      - 1

.. conf_minion:: lazy_loader_strict_matching

``lazy_loader_strict_matching``
-------------------------------

.. versionadded:: 3006.19

Default: ``False``

.. versionchanged:: 3008.0
    The default will change to ``True`` in version 3008.0.

Reduces memory usage by skipping expensive module file searches.

When disabled (default), the loader searches for modules in three stages:

1. Exact filename match (e.g., ``test.py`` for module ``test``)
2. Partial filename matches (files containing "test" in the name)
3. Expensive search through every module file

When enabled, stage 3 is skipped. Virtual module names (``__virtualname__``)
continue to work if stages 1 or 2 find the module file.

.. code-block:: yaml

    lazy_loader_strict_matching: True

Minion Execution Module Management
==================================

.. conf_minion:: disable_modules

``disable_modules``
-------------------

Default: ``[]`` (all execution modules are enabled by default)

The event may occur in which the administrator desires that a minion should not
be able to execute a certain module.

However, the ``sys`` module is built into the minion and cannot be disabled.

This setting can also tune the minion. Because all modules are loaded into system
memory, disabling modules will lower the minion's memory footprint.

Modules should be specified according to their file name on the system and not by
their virtual name. For example, to disable ``cmd``, use the string ``cmdmod`` which
corresponds to ``salt.modules.cmdmod``.

.. code-block:: yaml

    disable_modules:
      - test
      - solr

.. conf_minion:: disable_returners

``disable_returners``
---------------------

Default: ``[]`` (all returners are enabled by default)

If certain returners should be disabled, this is the place

.. code-block:: yaml

    disable_returners:
      - mongo_return


.. conf_minion:: enable_whitelist_modules

``whitelist_modules``
---------------------

Default: ``[]`` (Module whitelisting is disabled.  Adding anything to the config option
will cause only the listed modules to be enabled.  Modules not in the list will
not be loaded.)

This option is the reverse of disable_modules. If enabled, only execution modules in this
list will be loaded and executed on the minion.

Note that this is a very large hammer and it can be quite difficult to keep the minion working
the way you think it should since Salt uses many modules internally itself.  At a bare minimum
you need the following enabled or else the minion won't start.

.. code-block:: yaml

    whitelist_modules:
      - cmdmod
      - test
      - config


.. conf_minion:: module_dirs

``module_dirs``
---------------

Default: ``[]``

A list of extra directories to search for Salt modules

.. code-block:: yaml

    module_dirs:
      - /var/lib/salt/modules

.. conf_minion:: returner_dirs

``returner_dirs``
-----------------

Default: ``[]``

A list of extra directories to search for Salt returners

.. code-block:: yaml

    returner_dirs:
      - /var/lib/salt/returners

.. conf_minion:: states_dirs

``states_dirs``
---------------

Default: ``[]``

A list of extra directories to search for Salt states

.. code-block:: yaml

    states_dirs:
      - /var/lib/salt/states


.. conf_minion:: grains_dirs

``grains_dirs``
---------------

Default: ``[]``

A list of extra directories to search for Salt grains

.. code-block:: yaml

    grains_dirs:
      - /var/lib/salt/grains


.. conf_minion:: render_dirs

``render_dirs``
---------------

Default: ``[]``

A list of extra directories to search for Salt renderers

.. code-block:: yaml

    render_dirs:
      - /var/lib/salt/renderers

.. conf_minion:: utils_dirs

``utils_dirs``
--------------

Default: ``[]``

A list of extra directories to search for Salt utilities

.. code-block:: yaml

    utils_dirs:
      - /var/lib/salt/utils

.. conf_minion:: cython_enable

``cython_enable``
-----------------

Default: ``False``

Set this value to true to enable auto-loading and compiling of ``.pyx`` modules,
This setting requires that ``gcc`` and ``cython`` are installed on the minion.

.. code-block:: yaml

    cython_enable: False

.. conf_minion:: enable_zip_modules

``enable_zip_modules``
----------------------

.. versionadded:: 2015.8.0

Default: ``False``

Set this value to true to enable loading of zip archives as extension modules.
This allows for packing module code with specific dependencies to avoid conflicts
and/or having to install specific modules' dependencies in system libraries.

.. code-block:: yaml

    enable_zip_modules: False

.. conf_minion:: providers

``providers``
-------------

Default: (empty)

A module provider can be statically overwritten or extended for the minion via
the ``providers`` option. This can be done :ref:`on an individual basis in an
SLS file <state-providers>`, or globally here in the minion config, like
below.

.. code-block:: yaml

    providers:
      service: systemd

.. conf_minion:: modules_max_memory

``modules_max_memory``
----------------------

Default: ``-1``

Specify a max size (in bytes) for modules on import. This feature is currently
only supported on \*NIX operating systems and requires psutil.

.. code-block:: yaml

    modules_max_memory: -1

.. conf_minion:: extmod_whitelist
.. conf_minion:: extmod_blacklist

``extmod_whitelist/extmod_blacklist``
-------------------------------------

.. versionadded:: 2017.7.0

By using this dictionary, the modules that are synced to the minion's extmod cache using `saltutil.sync_*` can be
limited.  If nothing is set to a specific type, then all modules are accepted.  To block all modules of a specific type,
whitelist an empty list.

.. code-block:: yaml

    extmod_whitelist:
      modules:
        - custom_module
      engines:
        - custom_engine
      pillars: []

    extmod_blacklist:
      modules:
        - specific_module

Valid options:

  - beacons
  - clouds
  - sdb
  - modules
  - states
  - grains
  - renderers
  - returners
  - proxy
  - engines
  - output
  - utils
  - pillar


Top File Settings
=================


.. conf_minion:: state_top

``state_top``
-------------

Default: ``top.sls``

The state system uses a "top" file to tell the minions what environment to
use and what modules to use. The state_top file is defined relative to the
root of the base environment.

.. code-block:: yaml

    state_top: top.sls

.. conf_minion:: state_top_saltenv

``state_top_saltenv``
---------------------

This option has no default value. Set it to an environment name to ensure that
*only* the top file from that environment is considered during a
:ref:`highstate <running-highstate>`.

.. note::
    Using this value does not change the merging strategy. For instance, if
    :conf_minion:`top_file_merging_strategy` is set to ``merge``, and
    :conf_minion:`state_top_saltenv` is set to ``foo``, then any sections for
    environments other than ``foo`` in the top file for the ``foo`` environment
    will be ignored. With :conf_minion:`state_top_saltenv` set to ``base``, all
    states from all environments in the ``base`` top file will be applied,
    while all other top files are ignored. The only way to set
    :conf_minion:`state_top_saltenv` to something other than ``base`` and not
    have the other environments in the targeted top file ignored, would be to
    set :conf_minion:`top_file_merging_strategy` to ``merge_all``.

.. code-block:: yaml

    state_top_saltenv: dev

.. conf_minion:: top_file_merging_strategy

``top_file_merging_strategy``
-----------------------------

.. versionchanged:: 2016.11.0
    A ``merge_all`` strategy has been added.

Default: ``merge``

When no specific fileserver environment (a.k.a. ``saltenv``) has been specified
for a :ref:`highstate <running-highstate>`, all environments' top files are
inspected. This config option determines how the SLS targets in those top files
are handled.

When set to ``merge``, the ``base`` environment's top file is evaluated first,
followed by the other environments' top files. The first target expression
(e.g. ``'*'``) for a given environment is kept, and when the same target
expression is used in a different top file evaluated later, it is ignored.
Because ``base`` is evaluated first, it is authoritative. For example, if there
is a target for ``'*'`` for the ``foo`` environment in both the ``base`` and
``foo`` environment's top files, the one in the ``foo`` environment would be
ignored. The environments will be evaluated in no specific order (aside from
``base`` coming first). For greater control over the order in which the
environments are evaluated, use :conf_minion:`env_order`. Note that, aside from
the ``base`` environment's top file, any sections in top files that do not
match that top file's environment will be ignored. So, for example, a section
for the ``qa`` environment would be ignored if it appears in the ``dev``
environment's top file. To keep use cases like this from being ignored, use the
``merge_all`` strategy.

When set to ``same``, then for each environment, only that environment's top
file is processed, with the others being ignored. For example, only the ``dev``
environment's top file will be processed for the ``dev`` environment, and any
SLS targets defined for ``dev`` in the ``base`` environment's (or any other
environment's) top file will be ignored. If an environment does not have a top
file, then the top file from the :conf_minion:`default_top` config parameter
will be used as a fallback.

When set to ``merge_all``, then all states in all environments in all top files
will be applied. The order in which individual SLS files will be executed will
depend on the order in which the top files were evaluated, and the environments
will be evaluated in no specific order. For greater control over the order in
which the environments are evaluated, use :conf_minion:`env_order`.

.. code-block:: yaml

    top_file_merging_strategy: same

.. conf_minion:: env_order

``env_order``
-------------

Default: ``[]``

When :conf_minion:`top_file_merging_strategy` is set to ``merge``, and no
environment is specified for a :ref:`highstate <running-highstate>`, this
config option allows for the order in which top files are evaluated to be
explicitly defined.

.. code-block:: yaml

    env_order:
      - base
      - dev
      - qa

.. conf_minion:: default_top

``default_top``
---------------

Default: ``base``

When :conf_minion:`top_file_merging_strategy` is set to ``same``, and no
environment is specified for a :ref:`highstate <running-highstate>` (i.e.
:conf_minion:`environment` is not set for the minion), this config option
specifies a fallback environment in which to look for a top file if an
environment lacks one.

.. code-block:: yaml

    default_top: dev

.. conf_minion:: startup_states

``startup_states``
------------------

Default: ``''``

States to run when the minion daemon starts. To enable, set ``startup_states`` to:

- ``highstate``: Execute state.highstate
- ``sls``: Read in the sls_list option and execute the named sls files
- ``top``: Read top_file option and execute based on that file on the Master

.. code-block:: yaml

    startup_states: ''

.. conf_minion:: sls_list

``sls_list``
------------

Default: ``[]``

List of states to run when the minion starts up if ``startup_states`` is set to ``sls``.

.. code-block:: yaml

    sls_list:
      - edit.vim
      - hyper

.. conf_minion:: start_event_grains

``start_event_grains``
----------------------

Default: ``[]``

List of grains to pass in start event when minion starts up.

.. code-block:: yaml

    start_event_grains:
      - machine_id
      - uuid

.. conf_minion:: top_file

``top_file``
------------

Default: ``''``

Top file to execute if ``startup_states`` is set to ``top``.

.. code-block:: yaml

    top_file: ''


State Management Settings
=========================

.. conf_minion:: renderer

``renderer``
------------

Default: ``jinja|yaml``

The default renderer used for local state executions

.. code-block:: yaml

    renderer: jinja|json

.. conf_minion:: test

``test``
--------

Default: ``False``

Set all state calls to only test if they are going to actually make changes
or just post what changes are going to be made.

.. code-block:: yaml

    test: False

.. conf_minion:: state_aggregate

``state_aggregate``
-------------------

Default: ``False``

Automatically aggregate all states that have support for ``mod_aggregate`` by
setting to ``True``.

.. code-block:: yaml

    state_aggregate: True

Or pass a list of state module names to automatically
aggregate just those types.

.. code-block:: yaml

    state_aggregate:
      - pkg

.. conf_minion:: state_queue

``state_queue``
---------------

Default: ``False``

Instead of failing immediately when another state run is in progress, a value
of ``True`` will queue the new state run to begin running once the other has
finished.

The queue is implemented as a disk-based FIFO queue, minimizing memory usage
regardless of queue depth. Jobs in the state queue are processed by a background
thread and will bypass :conf_minion:`process_count_max` limits when they are
ready to execute, ensuring they are not starved by other workloads.

.. code-block:: yaml

    state_queue: True

Additionally, it can be set to an integer representing the maximum queue size
which can be attained before the state runs will fail to be queued. This can
prevent runaway conditions where new threads are started until system
performance is hampered.

.. code-block:: yaml

    state_queue: 2

.. conf_minion:: state_max_parallel

``state_max_parallel``
----------------------

Default: ``0``

Limit the number of ``parallel: true`` states that can be running at the same time.
By default, there is no limit.

.. conf_minion:: state_verbose

``state_verbose``
-----------------

Default: ``True``

Controls the verbosity of state runs. By default, the results of all states are
returned, but setting this value to ``False`` will cause salt to only display
output for states that failed or states that have changes.

.. code-block:: yaml

    state_verbose: True

.. conf_minion:: state_output

``state_output``
----------------

Default: ``full``

The state_output setting controls which results will be output full multi line:

* ``full``, ``terse`` - each state will be full/terse
* ``mixed`` - only states with errors will be full
* ``changes`` - states with changes and errors will be full

``full_id``, ``mixed_id``, ``changes_id`` and ``terse_id`` are also allowed;
when set, the state ID will be used as name in the output.

Any of the above modes can be suffixed with ``_color`` (e.g. ``full_color``,
``mixed_color``) to enable colorized unified diff output in the changes
section. Added lines are shown in green, removed lines in red, hunk headers
in cyan, and context lines in gray. All other output behavior is identical to
the mode without the ``_color`` suffix.

.. code-block:: yaml

    state_output: full

.. code-block:: yaml

    state_output: full_color

.. conf_minion:: state_output_diff

``state_output_diff``
---------------------

Default: ``False``

The state_output_diff setting changes whether or not the output from
successful states is returned. Useful when even the terse output of these
states is cluttering the logs. Set it to True to ignore them.

.. code-block:: yaml

    state_output_diff: False

.. conf_minion:: state_output_profile

``state_output_profile``
------------------------

Default: ``True``

The ``state_output_profile`` setting changes whether profile information
will be shown for each state run.

.. code-block:: yaml

    state_output_profile: True

.. conf_minion:: state_output_pct

``state_output_pct``
--------------------

Default: ``False``

The ``state_output_pct`` setting changes whether success and failure information
as a percent of total actions will be shown for each state run.

.. code-block:: yaml

    state_output_pct: False

.. conf_minion:: state_compress_ids

``state_compress_ids``
----------------------

Default: ``False``

The ``state_compress_ids`` setting aggregates information about states which
have multiple "names" under the same state ID in the highstate output.

.. code-block:: yaml

    state_compress_ids: False

.. conf_minion:: autoload_dynamic_modules

``autoload_dynamic_modules``
----------------------------

Default: ``True``

autoload_dynamic_modules turns on automatic loading of modules found in the
environments on the master. This is turned on by default. To turn off
auto-loading modules when states run, set this value to ``False``.

.. code-block:: yaml

    autoload_dynamic_modules: True

.. conf_minion:: clean_dynamic_modules

``clean_dynamic_modules``
-------------------------

Default: ``True``

clean_dynamic_modules keeps the dynamic modules on the minion in sync with
the dynamic modules on the master. This means that if a dynamic module is
not on the master it will be deleted from the minion. By default this is
enabled and can be disabled by changing this value to ``False``.

.. code-block:: yaml

    clean_dynamic_modules: True

.. note::

    If ``extmod_whitelist`` is specified, modules which are not whitelisted will also be cleaned here.

.. conf_minion:: environment
.. conf_minion:: saltenv

``saltenv``
-----------

.. versionchanged:: 2018.3.0
    Renamed from ``environment`` to ``saltenv``. If ``environment`` is used,
    ``saltenv`` will take its value. If both are used, ``environment`` will be
    ignored and ``saltenv`` will be used.

The default fileserver environment to use when copying files and applying states.

.. code-block:: yaml

    saltenv: dev

.. conf_minion:: lock_saltenv

``lock_saltenv``
----------------

.. versionadded:: 2018.3.0

Default: ``False``

For purposes of running states, this option prevents using the ``saltenv``
argument to manually set the environment. This is useful to keep a minion which
has the :conf_minion:`saltenv` option set to ``dev`` from running states from
an environment other than ``dev``.

.. code-block:: yaml

    lock_saltenv: True

.. conf_minion:: snapper_states

``snapper_states``
------------------

Default: False

The `snapper_states` value is used to enable taking snapper snapshots before
and after salt state runs. This allows for state runs to be rolled back.

For snapper states to function properly snapper needs to be installed and
enabled.

.. code-block:: yaml

    snapper_states: True

.. conf_minion:: snapper_states_config

``snapper_states_config``
-------------------------

Default: ``root``

Snapper can execute based on a snapper configuration. The configuration
needs to be set up before snapper can use it. The default configuration
is ``root``, this default makes snapper run on SUSE systems using the
default configuration set up at install time.

.. code-block:: yaml

    snapper_states_config: root

``global_state_conditions``
---------------------------

Default: ``None``

If set, this parameter expects a dictionary of state module names as keys and a
list of conditions which must be satisfied in order to run any functions in that
state module.

.. code-block:: yaml

    global_state_conditions:
      "*": ["G@global_noop:false"]
      service: ["not G@virtual_subtype:chroot"]

File Directory Settings
=======================

.. conf_minion:: file_client

``file_client``
---------------

Default: ``remote``

The client defaults to looking on the master server for files, but can be
directed to look on the minion by setting this parameter to ``local``.

.. code-block:: yaml

    file_client: remote

.. conf_minion:: use_master_when_local

``use_master_when_local``
-------------------------

Default: ``False``

When using a local :conf_minion:`file_client`, this parameter is used to allow
the client to connect to a master for remote execution.

.. code-block:: yaml

    use_master_when_local: False

.. conf_minion:: file_roots

``file_roots``
--------------

Default:

.. code-block:: yaml

    base:
      - /srv/salt

When using a local :conf_minion:`file_client`, this parameter is used to setup
the fileserver's environments. This parameter operates identically to the
:conf_master:`master config parameter <file_roots>` of the same name.

.. code-block:: yaml

    file_roots:
      base:
        - /srv/salt
      dev:
        - /srv/salt/dev/services
        - /srv/salt/dev/states
      prod:
        - /srv/salt/prod/services
        - /srv/salt/prod/states

.. conf_minion:: fileserver_followsymlinks

``fileserver_followsymlinks``
-----------------------------

.. versionadded:: 2014.1.0

Default: ``True``

By default, the file_server follows symlinks when walking the filesystem tree.
Currently this only applies to the default roots fileserver_backend.

.. code-block:: yaml

    fileserver_followsymlinks: True

.. conf_minion:: fileserver_ignoresymlinks

``fileserver_ignoresymlinks``
-----------------------------

.. versionadded:: 2014.1.0

Default: ``False``

If you do not want symlinks to be treated as the files they are pointing to,
set ``fileserver_ignoresymlinks`` to ``True``. By default this is set to
False. When set to ``True``, any detected symlink while listing files on the
Master will not be returned to the Minion.

.. code-block:: yaml

    fileserver_ignoresymlinks: False

.. conf_minion:: hash_type

``hash_type``
-------------

Default: ``sha256``

The hash_type is the hash to use when discovering the hash of a file on the
local fileserver. The default is sha256, but md5, sha1, sha224, sha384, and
sha512 are also supported.

.. code-block:: yaml

    hash_type: sha256


.. _pillar-configuration-minion:

Pillar Configuration
====================

.. conf_minion:: pillar_roots

``pillar_roots``
----------------

Default:

.. code-block:: yaml

    base:
      - /srv/pillar

When using a local :conf_minion:`file_client`, this parameter is used to setup
the pillar environments.

.. code-block:: yaml

    pillar_roots:
      base:
        - /srv/pillar
      dev:
        - /srv/pillar/dev
      prod:
        - /srv/pillar/prod

.. conf_minion:: on_demand_ext_pillar

``on_demand_ext_pillar``
------------------------

.. versionadded:: 2016.3.6,2016.11.3,2017.7.0

Default: ``['libvirt', 'virtkey']``

When using a local :conf_minion:`file_client`, this option controls which
external pillars are permitted to be used on-demand using :py:func:`pillar.ext
<salt.modules.pillar.ext>`.

.. code-block:: yaml

    on_demand_ext_pillar:
      - libvirt
      - virtkey
      - git

.. warning::
    This will allow a masterless minion to request specific pillar data via
    :py:func:`pillar.ext <salt.modules.pillar.ext>`, and may be considered a
    security risk. However, pillar data generated in this way will not affect
    the :ref:`in-memory pillar data `, so this risk is
    limited to instances in which states/modules/etc. (built-in or custom) rely
    upon pillar data generated by :py:func:`pillar.ext
    <salt.modules.pillar.ext>`.

.. conf_minion:: decrypt_pillar

``decrypt_pillar``
------------------

.. versionadded:: 2017.7.0

Default: ``[]``

A list of paths to be recursively decrypted during pillar compilation.

.. code-block:: yaml

    decrypt_pillar:
      - 'foo:bar': gpg
      - 'lorem:ipsum:dolor'

Entries in this list can be formatted either as a simple string, or as a
key/value pair, with the key being the pillar location, and the value being the
renderer to use for pillar decryption. If the former is used, the renderer
specified by :conf_minion:`decrypt_pillar_default` will be used.

.. conf_minion:: decrypt_pillar_delimiter

``decrypt_pillar_delimiter``
----------------------------

.. versionadded:: 2017.7.0

Default: ``:``

The delimiter used to distinguish nested data structures in the
:conf_minion:`decrypt_pillar` option.

.. code-block:: yaml

    decrypt_pillar_delimiter: '|'
    decrypt_pillar:
      - 'foo|bar': gpg
      - 'lorem|ipsum|dolor'

.. conf_minion:: decrypt_pillar_default

``decrypt_pillar_default``
--------------------------

.. versionadded:: 2017.7.0

Default: ``gpg``

The default renderer used for decryption, if one is not specified for a given
pillar key in :conf_minion:`decrypt_pillar`.

.. code-block:: yaml

    decrypt_pillar_default: my_custom_renderer

.. conf_minion:: decrypt_pillar_renderers

``decrypt_pillar_renderers``
----------------------------

.. versionadded:: 2017.7.0

Default: ``['gpg']``

List of renderers which are permitted to be used for pillar decryption.

.. code-block:: yaml

    decrypt_pillar_renderers:
      - gpg
      - my_custom_renderer

.. conf_minion:: gpg_decrypt_must_succeed

``gpg_decrypt_must_succeed``
----------------------------

.. versionadded:: 3005

Default: ``False``

If this is ``True`` and the ciphertext could not be decrypted, then an error is
raised.

Sending the ciphertext through basically is *never* desired, for example if a
state is setting a database password from pillar and gpg rendering fails, then
the state will update the password to the ciphertext, which by definition is
not encrypted.

.. warning::

    The value defaults to ``False`` for backwards compatibility.  In the
    ``Chlorine`` release, this option will default to ``True``.

.. code-block:: yaml

    gpg_decrypt_must_succeed: False

.. conf_minion:: pillarenv

``pillarenv``
-------------

Default: ``None``

Isolates the pillar environment on the minion side. This functions the same as
the environment setting, but for pillar instead of states.

.. code-block:: yaml

    pillarenv: dev

.. conf_minion:: pillarenv_from_saltenv

``pillarenv_from_saltenv``
--------------------------

.. versionadded:: 2017.7.0

Default: ``False``

When set to ``True``, the :conf_minion:`pillarenv` value will assume the value
of the effective saltenv when running states. This essentially makes ``salt '*'
state.sls mysls saltenv=dev`` equivalent to ``salt '*' state.sls mysls
saltenv=dev pillarenv=dev``. If :conf_minion:`pillarenv` is set, either in the
minion config file or via the CLI, it will override this option.

.. code-block:: yaml

    pillarenv_from_saltenv: True

.. conf_minion:: pillar_raise_on_missing

``pillar_raise_on_missing``
---------------------------

.. versionadded:: 2015.5.0

Default: ``False``

Set this option to ``True`` to force a ``KeyError`` to be raised whenever an
attempt to retrieve a named value from pillar fails. When this option is set
to ``False``, the failed attempt returns an empty string.

.. conf_minion:: minion_pillar_cache

``minion_pillar_cache``
-----------------------

.. versionadded:: 2016.3.0

Default: ``False``

The minion can locally cache rendered pillar data under
:conf_minion:`cachedir`/pillar. This allows a temporarily disconnected minion
to access previously cached pillar data by invoking salt-call with the --local
and --pillar_root=:conf_minion:`cachedir`/pillar options. Before enabling this
setting consider that the rendered pillar may contain security sensitive data.
Appropriate access restrictions should be in place. By default the saved pillar
data will be readable only by the user account running salt. By default this
feature is disabled, to enable set minion_pillar_cache to ``True``.

.. code-block:: yaml

    minion_pillar_cache: False

.. conf_minion:: file_recv_max_size

``file_recv_max_size``
----------------------

.. versionadded:: 2014.7.0

Default: ``100``

Set a hard-limit on the size of the files that can be pushed to the master.
It will be interpreted as megabytes.

.. code-block:: yaml

    file_recv_max_size: 100

.. conf_minion:: pass_to_ext_pillars

``pass_to_ext_pillars``
-----------------------

Specify a list of configuration keys whose values are to be passed to
external pillar functions.

Suboptions can be specified using the ':' notation (i.e. ``option:suboption``)

The values are merged and included in the ``extra_minion_data`` optional
parameter of the external pillar function.  The ``extra_minion_data`` parameter
is passed only to the external pillar functions that have it explicitly
specified in their definition.

If the config contains

.. code-block:: yaml

    opt1: value1
    opt2:
      subopt1: value2
      subopt2: value3

    pass_to_ext_pillars:
      - opt1
      - opt2: subopt1

the ``extra_minion_data`` parameter will be

.. code-block:: python

    {"opt1": "value1", "opt2": {"subopt1": "value2"}}

``ssh_merge_pillar``
--------------------

.. versionadded:: 2018.3.2

Default: ``True``

Merges the compiled pillar data with the pillar data already available globally.
This is useful when using ``salt-ssh`` or ``salt-call --local`` and overriding the pillar
data in a state file:

.. code-block:: yaml

    apply_showpillar:
      module.run:
        - name: state.apply
        - mods:
          - showpillar
        - kwargs:
              pillar:
                  test: "foo bar"

If set to ``True``, the ``showpillar`` state will have access to the
global pillar data.

If set to ``False``, only the overriding pillar data will be available
to the ``showpillar`` state.

Security Settings
=================

.. conf_minion:: open_mode

``open_mode``
-------------

Default: ``False``

Open mode can be used to clean out the PKI key received from the Salt master,
turn on open mode, restart the minion, then turn off open mode and restart the
minion to clean the keys.

.. code-block:: yaml

    open_mode: False

.. conf_minion:: master_finger

``master_finger``
-----------------

Default: ``''``

Fingerprint of the master public key to validate the identity of your Salt master
before the initial key exchange. The master fingerprint can be found as ``master.pub`` by running
"salt-key -F master" on the Salt master.

.. code-block:: yaml

   master_finger: 'ba:30:65:2a:d6:9e:20:4f:d8:b2:f3:a7:d4:65:11:13'

.. conf_minion:: keysize

``keysize``
-----------

Default: ``2048``

The size of key that should be generated when creating new keys.

.. code-block:: yaml

    keysize: 2048

.. conf_minion:: permissive_pki_access

``permissive_pki_access``
-------------------------

Default: ``False``

Enable permissive access to the salt keys. This allows you to run the
master or minion as root, but have a non-root group be given access to
your pki_dir. To make the access explicit, root must belong to the group
you've given access to. This is potentially quite insecure.

.. code-block:: yaml

    permissive_pki_access: False

.. conf_minion:: verify_master_pubkey_sign

``verify_master_pubkey_sign``
-----------------------------

Default: ``False``

Enables verification of the master-public-signature returned by the master in
auth-replies. Please see the tutorial on how to configure this properly
`Multimaster-PKI with Failover Tutorial <https://docs.saltproject.io/en/latest/topics/tutorials/multimaster_pki.html>`_

.. versionadded:: 2014.7.0

.. code-block:: yaml

    verify_master_pubkey_sign: True

If this is set to ``True``, :conf_master:`master_sign_pubkey` must be also set
to ``True`` in the master configuration file.


.. conf_minion:: master_sign_key_name

``master_sign_key_name``
------------------------

Default: ``master_sign``

The filename without the *.pub* suffix of the public key that should be used
for verifying the signature from the master. The file must be located in the
minion's pki directory.

.. versionadded:: 2014.7.0

.. code-block:: yaml

    master_sign_key_name: <filename_without_suffix>

.. conf_minion:: autosign_grains

``autosign_grains``
-------------------

.. versionadded:: 2018.3.0

Default: ``not defined``

The grains that should be sent to the master on authentication to decide if
the minion's key should be accepted automatically.

Please see the :ref:`Autoaccept Minions from Grains <tutorial-autoaccept-grains>`
documentation for more information.

.. code-block:: yaml

    autosign_grains:
      - uuid
      - server_id

.. conf_minion:: always_verify_signature

``always_verify_signature``
---------------------------

Default: ``False``

If :conf_minion:`verify_master_pubkey_sign` is enabled, the signature is only verified
if the public-key of the master changes. If the signature should always be verified,
this can be set to ``True``.

.. versionadded:: 2014.7.0

.. code-block:: yaml

    always_verify_signature: True

.. conf_minion:: cmd_blacklist_glob

``cmd_blacklist_glob``
----------------------

Default: ``[]``

If :conf_minion:`cmd_blacklist_glob` is enabled then any shell command called over
remote execution or via salt-call will be checked against the glob matches found in
the `cmd_blacklist_glob` list and any matched shell command will be blocked.

.. note::

    This blacklist is only applied to direct executions made by the `salt` and
    `salt-call` commands. This does NOT blacklist commands called from states
    or shell commands executed from other modules.

.. versionadded:: 2016.11.0

.. code-block:: yaml

    cmd_blacklist_glob:
      - 'rm * '
      - 'cat /etc/* '

.. conf_minion:: cmd_whitelist_glob

``cmd_whitelist_glob``
----------------------

Default: ``[]``

If :conf_minion:`cmd_whitelist_glob` is enabled then any shell command called over
remote execution or via salt-call will be checked against the glob matches found in
the `cmd_whitelist_glob` list and any shell command NOT found in the list will be
blocked. If `cmd_whitelist_glob` is NOT SET, then all shell commands are permitted.

.. note::

    This whitelist is only applied to direct executions made by the `salt` and
    `salt-call` commands. This does NOT restrict commands called from states
    or shell commands executed from other modules.

.. v