Skip to content

GitOps Without Kubernetes

GitOps is usually taught with Kubernetes, but the pattern is older and broader: desired state in git, automation converging reality. Here's what it looks like without a cluster in sight.

Why this matters

If your workplace teaches GitOps as "Kubernetes plus Terraform," it's easy to conclude it doesn't apply to your servers, your homelab, or your dotfiles. It does. The principles don't mention containers.

Servers and fleets

The classic non-K8s setup: a repo holds Ansible playbooks (or plain scripts) describing each machine's configuration. A scheduled run — cron, a CI pipeline, Ansible Tower/AWX — pulls the repo and applies it. Hand-edits get overwritten on the next run, which is the point.

What lives in the repo:

  • Package lists and versions.
  • Service configs (nginx, SSH, firewall rules).
  • User accounts and SSH keys.
  • Cron jobs and timers.

This is how many small teams run a dozen servers sanely: the fleet's configuration is a git repo you can read, review, and revert.

Dotfiles and personal machines

Your own configuration — shell, editor, git settings — is desired state for your machines. Tools like chezmoi or yadm keep dotfiles in git and apply them per-machine, with templates for the differences (work laptop vs. home server). New machine setup becomes "install the tool, point it at the repo" instead of an afternoon of remembering settings.

What changes without Kubernetes

With Kubernetes Without it
Manifests (YAML) describe state Playbooks, scripts, config files describe state
ArgoCD/Flux reconcile Cron, CI, or config management reconciles
kubectl diff shows drift Dry runs (ansible --check) show drift
Rollback is a revert + sync Rollback is a revert + re-run

The loop is the same; only the vocabulary changes.

What doesn't fit as well

Kubernetes gives you a lot for free: a uniform API, built-in diffing, mature agents. Without it, you assemble more yourself — drift detection especially tends to be "re-run and see what changes" rather than continuous. That's fine for many setups; be honest about the gap rather than pretending a cron job is ArgoCD.

Start small

Pick one thing that's currently snowflake configuration — the nginx config on one server, your dotfiles — put it in git, and automate its application. One loop, working, teaches more than a grand design.

For concrete setups to copy, see Non-Kubernetes Patterns: ansible-pull fleets, cron apply scripts, etckeeper, chezmoi dotfiles, compose-from-git, drift reporting, and the Terraform split.

Next: Tools Overview.