diff --git a/.woodpecker.yml b/.woodpecker.yml index 54c4ba3..917bed4 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,12 +1,17 @@ # ============================================================================= -# Pipeline 1: CI/CD -# Triggered by: pull_request (validate + drift-check) -# push to master (validate + deploy + post-deploy sync metric) +# Single pipeline – all event types handled via step-level when conditions: +# pull_request → syntax-check, validate, drift-check +# push (master) → syntax-check, validate, deploy, update-sync-metric +# cron → gitops_sync_check (read-only drift check, no deploy) +# +# NOTE: Woodpecker does not support multiple YAML documents (---) in one file. +# All pipelines must live in a single document with step-level filtering. # ============================================================================= when: - event: pull_request - event: push branch: master + - event: cron steps: # --------------------------------------------------------------------------- @@ -18,6 +23,10 @@ steps: ANSIBLE_CONFIG: ansible.cfg commands: - ansible-playbook -i ansible/inventory/hosts.yml --syntax-check ansible/playbooks/*.yml + when: + - event: pull_request + - event: push + branch: master # --------------------------------------------------------------------------- # validate: Validate server state – runs on pull_request and push @@ -34,6 +43,10 @@ steps: - printf '%s\n' "$${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ansible-playbook -i ansible/inventory/hosts.yml ansible/playbooks/validate.yml + when: + - event: pull_request + - event: push + branch: master # --------------------------------------------------------------------------- # drift-check: Compare server config to Git – runs on pull_request only @@ -73,10 +86,9 @@ steps: event: push # --------------------------------------------------------------------------- - # update-sync-metric: Verify post-deploy sync and report to Prometheus - # Runs drift-check after deploy; pushes gitops_sync_status metric. - # STATUS=1 means SYNCED, STATUS=0 means OUT_OF_SYNC. + # update-sync-metric: Post-deploy sync check + Prometheus metric push # Runs on push to master only, after deploy succeeds. + # STATUS=1 means SYNCED, STATUS=0 means OUT_OF_SYNC. # --------------------------------------------------------------------------- update-sync-metric: image: alpine/ansible:latest @@ -116,38 +128,16 @@ steps: branch: master event: push ---- -# ============================================================================= -# Pipeline 2: GitOps Sync Check (ArgoCD-style continuous drift detection) -# Triggered by: cron – runs every 2 minutes even without a new push -# -# Purpose: Detect manual configuration changes made directly on the server -# (outside Git). If someone edits /etc/rsyslog.conf by hand, the next cron -# run will catch it and mark the system OUT_OF_SYNC in Prometheus. -# -# This pipeline does NOT deploy anything – it is a read-only drift check. -# -# ─── Woodpecker Cron Configuration (set in the Woodpecker UI) ─────────────── -# Name: gitops-drift-check -# Branch: master -# Schedule: */2 * * * * -# ───────────────────────────────────────────────────────────────────────────── -# -# Required secrets (Woodpecker → Repository Settings → Secrets): -# SSH_PRIVATE_KEY – SSH key to reach the managed server -# -# Pushgateway URL is hardcoded (internal k8s service, not a secret): -# http://pushgateway.observability-stack.svc.cluster.local:9091 -# ============================================================================= -when: - event: cron - -steps: # --------------------------------------------------------------------------- - # gitops_sync_check: Read-only drift check + Prometheus metric push - # STATUS=1 → SYNCED (server matches Git) - # STATUS=0 → OUT_OF_SYNC (manual drift detected on server) - # Pipeline is marked FAILED when out of sync so it is visible in the UI. + # gitops_sync_check: ArgoCD-style cron drift check – read-only, no deploy + # Detects manual changes made directly on the server between pushes. + # STATUS=1 → SYNCED, STATUS=0 → OUT_OF_SYNC + # Pipeline marked FAILED when drift found so it is visible in the UI. + # + # ─── Woodpecker Cron UI settings ────────────────────────────────────────── + # Name: gitops_sync_check + # Branch: master + # Schedule: */2 * * * * # --------------------------------------------------------------------------- gitops_sync_check: image: alpine/ansible:latest @@ -160,7 +150,6 @@ steps: - | apk add --no-cache curl > /dev/null 2>&1 - # Prepare SSH key for remote server access mkdir -p ~/.ssh printf '%s\n' "$${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa @@ -184,5 +173,6 @@ steps: curl --silent --show-error --fail --data-binary @- \ "$${PUSHGATEWAY_URL}/metrics/job/gitops_rsyslog/instance/rsyslog-lab" - # Exit non-zero when out of sync so Woodpecker marks the pipeline FAILED exit $DRIFT_RC + when: + event: cron