7.6 KiB
rsyslog GitOps
Manage rsyslog configuration on Linux servers using Git as the single source of truth.
If it's not in Git, it doesn't belong on the server.
How it works in one sentence
Every change goes through Git. The pipeline makes sure the server always matches what's in Git — and if someone changes the server directly, the system detects it automatically.
The three pipelines
1. Pull Request — "Is this config safe?"
Triggered when you open or update a pull request.
Does not touch the live server beyond a basic reachability check.
Does not compare the PR content to the server (they're expected to differ before merge).
Open PR
│
├─► syntax-check Check the YAML/Ansible syntax is valid
│
└─► validate Connect to the server and verify rsyslog is running
and the current config is loadable
Pass = safe to review and merge.
Fail = syntax error or server is unreachable / config is broken.
2. Push to master — "Deploy and verify"
Triggered when a PR is merged into master.
Merge to master
│
├─► syntax-check Same lint check as PR
│
├─► validate Same server check as PR
│
├─► deploy Copy the new config files from Git to the server
│ and restart rsyslog
│
└─► update-sync-metric Run a diff between Git and the live server
│
├─ Matches? → push metric 1 (SYNCED)
└─ Differs? → push metric 0 (OUT_OF_SYNC)
Pass = new config is live and the server matches Git.
The sync result is always sent to Prometheus regardless of outcome.
3. Cron — "Is the server still synced?"
Runs automatically every 2 minutes, even with no new push.
This is the ArgoCD-style continuous check.
It only reads — never deploys anything.
Every 2 minutes (cron)
│
└─► gitops_sync_check SSH to the server, compare every managed config
file against the latest Git commit
│
├─ Matches? → push metric 1 (SYNCED)
└─ Differs? → push metric 0 (OUT_OF_SYNC)
Why this matters: if someone edits /etc/rsyslog.conf directly on the server
(bypassing Git), the next cron run catches it within 2 minutes and marks OUT_OF_SYNC.
Full flow diagram
Developer Woodpecker CI Linux Server Prometheus
│ │ │ │
│── open PR ───────────────►│ │ │
│ │── syntax-check │ │
│ │── validate ─────────────►│ │
│◄── PR ok / failed ────────│ │ │
│ │ │ │
│── merge to master ───────►│ │ │
│ │── syntax-check │ │
│ │── validate ─────────────►│ │
│ │── deploy ───────────────►│ write config │
│ │ │ restart rsyslog │
│ │── drift-check ──────────►│ compare files │
│ │ │◄────────────────────│
│ │── metric (1 or 0) ───────────────────────────►│
│ │ │ │
│ │ [every 2 min, no push] │ │
│ │── drift-check ──────────►│ compare files │
│ │── metric (1 or 0) ───────────────────────────►│
│ │ │ │
Someone edits the server directly (bad):
rogue admin Woodpecker CI Linux Server Prometheus
│ │ │ │
│── ssh rsyslog-lab │ │ │
│── vim /etc/rsyslog.conf ──────────────────────────► │ file changed │
│ │ │ │
│ [2 min later, cron runs] │ │
│ │── drift-check ──────────►│ diff detected │
│ │── metric 0 (OUT_OF_SYNC)────────────────────►│
│ │ │ alert fires
What is the sync metric?
gitops_sync_status{repo="rsyslog", server="rsyslog-lab"}
| Value | Meaning |
|---|---|
1 |
Server config matches Git (SYNCED) |
0 |
Server config differs from Git (OUT_OF_SYNC) |
Alert on gitops_sync_status == 0 in Grafana/Alertmanager.
What drift-check actually compares
The drift-check playbook compares files from the Woodpecker CI container (always the latest Git commit) against the live server. It checks:
/etc/rsyslog.conf— must matchfiles/rsyslog.confin Git/etc/rsyslog.d/30-lab.conf— must matchfiles/rsyslog.d/30-lab.confin Git- Any file managed by Git must not be missing from the server
Files on the server that are not in Git (e.g. 50-default.conf, 20-ufw.conf) are ignored — they are owned by the OS and are not our concern.
Repository structure
.woodpecker.yml CI pipeline definition
ansible/
inventory/
hosts.yml Server list
group_vars/all.yml Variables (paths, user, etc.)
playbooks/
validate.yml Check rsyslog is running and config loads
apply.yml Deploy config files from Git to server
drift-check.yml Compare Git files to live server (read-only)
files/
rsyslog.conf Main rsyslog config (source of truth)
rsyslog.d/
30-lab.conf Drop-in config for lab logging
Woodpecker cron setup
Go to Repository Settings → Crons → Add cron:
| Field | Value |
|---|---|
| Name | gitops_sync_check |
| Branch | master |
| Schedule | */2 * * * * |
Required secrets
Go to Repository Settings → Secrets:
| Name | Description |
|---|---|
SSH_PRIVATE_KEY |
Private key to SSH into the server |