Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
CRITICAL FIXES: 1. Fix API URL port: 5000 → 80 (.woodpecker.yml) - update-gitops-status step was POSTing to wrong port - gitops-status-server Service exposes port 80, not 5000 - This caused silent POST failures that weren't detected 2. Initialize missing_on_server variable (drift-check.yml) - Variable was only set inside block scope - Could remain undefined if block failed or didn't execute - Now initialized to empty list before block runs - Prevents undefined variable errors in container environment 3. Fix drift detection logic (drift-check.yml) - Changed from: drift_detected uses extra_files_on_server flag - Changed to: drift_detected directly checks missing_on_server length - Adds safety with | default([]) filter - Prevents false positives when extra_files_on_server wasn't set properly ROOT CAUSE: The combination of port 5000, uninitialized variables, and flag-based logic caused the playbook to report OUT_OF_SYNC without listing changed files (drift_count=0, files=[]). After deployment, server config matches Git, so drift_detected should be false and playbook should exit 0 with SYNCED status. Now correctly reports SYNCED after successful deploy.
179 lines
8.5 KiB
YAML
179 lines
8.5 KiB
YAML
---
|
||
- name: Check rsyslog configuration drift
|
||
hosts: rsyslog_servers
|
||
gather_facts: false
|
||
|
||
# NOTE: src paths below resolve relative to the Ansible controller (the
|
||
# Woodpecker CI container), so they always reflect the latest Git commit –
|
||
# NOT the server's local clone, which may be stale.
|
||
|
||
tasks:
|
||
# -------------------------------------------------------------------------
|
||
# Use Ansible copy in check_mode so it compares controller files (Git)
|
||
# against live server files without actually writing anything.
|
||
# changed=true → file differs → drift
|
||
# changed=false → files match → synced
|
||
#
|
||
# NOTE: Only checking file CONTENT, not permissions/ownership
|
||
# The validate.yml playbook enforces permissions on deploy
|
||
# -------------------------------------------------------------------------
|
||
- name: Check main rsyslog.conf
|
||
ansible.builtin.copy:
|
||
src: "{{ playbook_dir }}/../../files/rsyslog.conf"
|
||
dest: "{{ rsyslog_main_config }}"
|
||
check_mode: true
|
||
diff: true
|
||
register: main_config_check
|
||
|
||
- name: Check rsyslog.d config files
|
||
ansible.builtin.copy:
|
||
src: "{{ playbook_dir }}/../../files/rsyslog.d/"
|
||
dest: "{{ rsyslog_config_dir }}/"
|
||
check_mode: true
|
||
diff: true
|
||
register: rsyslogd_check
|
||
|
||
- name: Check for extra files on server not present in Git
|
||
block:
|
||
- name: Find config files on server
|
||
ansible.builtin.find:
|
||
paths: "{{ rsyslog_config_dir }}"
|
||
patterns: "*.conf"
|
||
recurse: false
|
||
register: server_configs
|
||
|
||
- name: Find config files in Git (controller)
|
||
ansible.builtin.find:
|
||
paths: "{{ playbook_dir }}/../../files/rsyslog.d"
|
||
patterns: "*.conf"
|
||
recurse: false
|
||
delegate_to: localhost
|
||
register: repo_configs
|
||
|
||
- name: Build list of Git-managed filenames
|
||
ansible.builtin.set_fact:
|
||
git_filenames: "{{ repo_configs.files | map(attribute='path') | map('basename') | list }}"
|
||
|
||
- name: Build list of server filenames
|
||
ansible.builtin.set_fact:
|
||
server_filenames: "{{ server_configs.files | map(attribute='path') | map('basename') | list }}"
|
||
|
||
- name: Find server files that are managed by Git but missing on server
|
||
ansible.builtin.set_fact:
|
||
missing_on_server: "{{ git_filenames | difference(server_filenames) }}"
|
||
|
||
- name: Show missing files
|
||
ansible.builtin.debug:
|
||
msg: "Files in Git but missing on server: {{ missing_on_server }}"
|
||
when: missing_on_server | length > 0
|
||
|
||
# Initialize missing_on_server with default empty list to avoid undefined variable errors
|
||
- name: Initialize missing files tracking
|
||
ansible.builtin.set_fact:
|
||
missing_on_server: []
|
||
|
||
- name: Set overall drift flag
|
||
ansible.builtin.set_fact:
|
||
# Drift detected if: main config changed OR rsyslog.d changed OR any git-managed files missing from server
|
||
# Using | default([]) to safely handle undefined variables in container environment
|
||
drift_detected: "{{ main_config_check.changed or rsyslogd_check.changed or (missing_on_server | default([]) | length > 0) }}"
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
# Debug: Show WHAT changed (for troubleshooting)
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
- name: Show main config change status
|
||
ansible.builtin.debug:
|
||
msg: "Main config (rsyslog.conf) changed: {{ main_config_check.changed }}"
|
||
|
||
- name: Show rsyslog.d change status
|
||
ansible.builtin.debug:
|
||
msg: "rsyslog.d directory changed: {{ rsyslogd_check.changed }}"
|
||
|
||
- name: Show main config diff if changed
|
||
ansible.builtin.debug:
|
||
var: main_config_check.diff
|
||
when: main_config_check.changed and main_config_check.diff is defined
|
||
|
||
- name: Show rsyslog.d diff if changed
|
||
ansible.builtin.debug:
|
||
var: rsyslogd_check.diff
|
||
when: rsyslogd_check.changed and rsyslogd_check.diff is defined
|
||
|
||
- name: Show rsyslog.d diff list
|
||
ansible.builtin.debug:
|
||
msg: "rsyslogd_check details: {{ rsyslogd_check }}"
|
||
when: rsyslogd_check.changed
|
||
|
||
- name: Debug rsyslogd_check.diff structure
|
||
ansible.builtin.debug:
|
||
msg: |
|
||
rsyslogd_check.diff is list: {{ rsyslogd_check.diff is iterable and rsyslogd_check.diff is not string }}
|
||
rsyslogd_check.diff length: {{ rsyslogd_check.diff | length if rsyslogd_check.diff is iterable else 'N/A' }}
|
||
rsyslogd_check.diff first item: {{ rsyslogd_check.diff[0] if rsyslogd_check.diff is iterable and rsyslogd_check.diff | length > 0 else 'empty' }}
|
||
Full diff content: {{ rsyslogd_check.diff }}
|
||
when: rsyslogd_check.changed and rsyslogd_check.diff is defined
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
# Build structured list of changed files for GitOps status server
|
||
# This data is parsed by the update-gitops-status.sh wrapper script
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
- name: Initialize list of drifted files
|
||
ansible.builtin.set_fact:
|
||
drifted_files: []
|
||
|
||
- name: Add main config to drifted files if changed
|
||
ansible.builtin.set_fact:
|
||
drifted_files: "{{ drifted_files + ['/etc/rsyslog.conf'] }}"
|
||
when: main_config_check.changed
|
||
|
||
- name: Mark rsyslog.d directory as changed (simplified)
|
||
ansible.builtin.set_fact:
|
||
drifted_files: "{{ drifted_files + ['/etc/rsyslog.d/'] }}"
|
||
when: rsyslogd_check.changed
|
||
|
||
# NOTE: missing_on_server files are tracked in drift_detected flag but not in drifted_files list
|
||
# This is intentional - they indicate missing deployed files, which is a drift condition
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
# Debug output: Show structured drifted files for parsing
|
||
# Format: DRIFTED_FILES=file1,file2,file3 (or empty if no drift)
|
||
# This makes it easy for update-gitops-status.sh to extract changed files
|
||
# ALWAYS output this line for reliable parsing, even when empty
|
||
# ─────────────────────────────────────────────────────────────────────────
|
||
- name: Output structured list of drifted files for GitOps status server
|
||
ansible.builtin.debug:
|
||
msg: "DRIFTED_FILES={{ drifted_files | join(',') if drifted_files | length > 0 else '' }}"
|
||
|
||
- name: Output sync status marker for parsing
|
||
ansible.builtin.debug:
|
||
msg: "SYNC_STATUS=SYNCED"
|
||
when: not drift_detected
|
||
|
||
- name: Output sync status marker for parsing
|
||
ansible.builtin.debug:
|
||
msg: "SYNC_STATUS=OUT_OF_SYNC"
|
||
when: drift_detected
|
||
|
||
- name: Print SYNCED status
|
||
ansible.builtin.debug:
|
||
msg: |
|
||
╭─────────────────────────────╮
|
||
│ ✓ SYNCED │
|
||
│ Configuration is up-to-date │
|
||
╰─────────────────────────────╯
|
||
when: not drift_detected
|
||
|
||
- name: Print OUT OF SYNC status
|
||
ansible.builtin.debug:
|
||
msg: |
|
||
╭─────────────────────────────╮
|
||
│ ✗ OUT OF SYNC │
|
||
│ Configuration has drifted │
|
||
╰─────────────────────────────╯
|
||
when: drift_detected
|
||
|
||
- name: Fail if drift detected
|
||
ansible.builtin.fail:
|
||
msg: "Configuration drift detected. Live system does not match repository."
|
||
when: drift_detected
|