GitOps for Salt: states in Git, the rest in Terraform
How to run Salt the GitOps way. Keep states in a Git repository with review before they reach a machine, manage runbooks, schedules and change windows as Terraform or OpenTofu code, and adopt an existing setup without recreating it.
GitOps means the repository is the source of truth: a change is a commit, review happens on the change before it lands, and what runs is what the repository says. Salt has supported part of this for years with gitfs, which serves states straight from a Git branch. What gitfs does not give you is the middle step: seeing what a push will change on your machines, and someone deciding before it does.
This is how to run Salt that way, with states in Git and everything around them as Terraform or OpenTofu code.
States in Git, reviewed before they publish#
With gitfs, a merge to the branch is live on the next highstate. That is fast, and it means a typo or a destructive state reaches production with no checkpoint after the pull request.
Gardience 1.18 keeps your states in Git and adds that checkpoint:
- Point a Git project at the folder that holds your
.slsfiles. - Push. A webhook syncs it at once, or choose Sync now.
- Review changes shows what publishing would do: new, changed and removed states, each with its diff, and anything skipped with the reason.
- An admin publishes, or you turn on Publish by itself after each sync so the merge is the approval. Either way every state is checked again before it is written, and the audit log records the commit.
States from Git change only in Git. Editing or deleting one in the console is refused with the project's name, so the console and the repository cannot drift apart. A folder that goes missing or is renamed never deletes your states.
Risk marked by what a state does, not its name#
The review marks each state by what applying it would do. A state that formats a disk, removes or stops the Salt agent, or deletes a whole drive is marked red: it cannot be undone. A risky but reversible one, such as stopping a firewall, deleting files or downloading and running a script, is marked yellow.
The check follows the content wherever it lives: module.run, either syntax, names given as objects, other spellings of the same function. Applying a red state then needs a second person, whether it came from Git or the console, and schedules never apply one on their own, because nobody would be there to approve it. A push to Git after a schedule was saved is checked again at the moment it would run.
Everything else as Terraform or OpenTofu#
States are half of the configuration. The rest is what decides when and where they run. With the Gardience provider for Terraform and OpenTofu, these live in code too:
- Node groups, by name, OS or pattern
- Saved states that are not in Git
- Event rules, such as "every new web server gets this state the moment it joins"
- Runbooks: a Salt function with a form, that people run from the console
- Change windows: when each group may change
- Schedules: what runs when
- Enrollments: a first-boot script per machine type, so a new machine joins and gets its baseline on boot
The provider uses a configure key that cannot run commands on machines already in the fleet. A schedule saved with a key starts off until an admin turns it on, and any later key change to what it runs turns it off again, so a leaked key cannot quietly change what an approved schedule does.
Adopt what you already built#
Most teams do not start from an empty repository. Admins have built groups, runbooks and schedules in the console for months. One call writes all of it as Terraform, with an import block for each item:
curl -fsS -H "Authorization: Bearer $GARDIENCE_API_KEY" "$GARDIENCE_URL/gardience/api/v1/export" > gardience.tf
terraform plan # each item to import, and no changes
terraform apply # adoptedThe export never writes secrets, API keys, enrollments, users or roles, or states kept in Git. Every export is in the audit log.
Questions#
Do I still need gitfs?#
Not for these states. The Salt master serves what was published from the Git project, after the review, so the branch never reaches machines unreviewed.
Does publishing run anything?#
No. Publishing writes states. Applying them is a separate step, with dry runs, change windows, locks, approvals and permissions as usual.
Terraform or OpenTofu?#
Either. The provider works with both.
Try Gardience on your own machines
One supported console for Windows and Linux on open-source Salt: patching, a scored STIG/CIS-aligned baseline, drift repair, event-driven automation, two-person approval and a tamper-evident audit log. Flat yearly pricing, not per node.
Free 90-day trial (25 nodes)See it work Compare