Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
CRITICAL FIX: Problem: drift-check.yml was using 'copy' module in check_mode, which compares: - File content ✓ - Permissions (owner, group, mode) ✗ - Ownership ✗ After deploy, files have root:root 0644 permissions. Even though content matches, the copy module marked files as 'changed' because permissions were being compared. This caused false OUT_OF_SYNC reports even when configuration was actually synced. Solution: Use MD5 checksum-based comparison instead: - Compare only file CONTENT using stat checksums - Ignore permissions/ownership differences - This is what matters for config management Also fixed URLs: - Changed back from port 80 to port 5000 (API only) - Updated service name to gitops-status-api Now drift detection only triggers on actual config changes, not permission differences. After successful deploy, should correctly report SYNCED status.
213 lines
9.7 KiB
YAML
213 lines
9.7 KiB
YAML
---
|
|
- name: Check rsyslog configuration drift
|
|
hosts: rsyslog_servers
|
|
gather_facts: false
|
|
|
|
# NOTE: This playbook compares file CONTENT ONLY using md5 checksums.
|
|
# It ignores permissions/ownership differences.
|
|
# Permissions are enforced during deploy (apply.yml)
|
|
|
|
tasks:
|
|
# -------------------------------------------------------------------------
|
|
# Checksum-based content comparison (ignores permissions/ownership)
|
|
# This is the only reliable way to detect actual config changes
|
|
# after deployment when permissions have been set.
|
|
# -------------------------------------------------------------------------
|
|
|
|
- name: Get MD5 checksum of Git version of rsyslog.conf
|
|
stat:
|
|
path: "{{ playbook_dir }}/../../files/rsyslog.conf"
|
|
delegate_to: localhost
|
|
register: git_rsyslog_conf_stat
|
|
|
|
- name: Get MD5 checksum of server version of rsyslog.conf
|
|
stat:
|
|
path: "{{ rsyslog_main_config }}"
|
|
register: server_rsyslog_conf_stat
|
|
|
|
- name: Compare rsyslog.conf content
|
|
set_fact:
|
|
main_config_check:
|
|
changed: "{{ git_rsyslog_conf_stat.stat.checksum != server_rsyslog_conf_stat.stat.checksum }}"
|
|
checksum_git: "{{ git_rsyslog_conf_stat.stat.checksum }}"
|
|
checksum_server: "{{ server_rsyslog_conf_stat.stat.checksum }}"
|
|
|
|
- name: Get checksums for rsyslog.d directory files
|
|
block:
|
|
- name: Find Git rsyslog.d files
|
|
find:
|
|
paths: "{{ playbook_dir }}/../../files/rsyslog.d"
|
|
patterns: "*.conf"
|
|
recurse: false
|
|
delegate_to: localhost
|
|
register: git_confd_files
|
|
|
|
- name: Find server rsyslog.d files
|
|
find:
|
|
paths: "{{ rsyslog_config_dir }}"
|
|
patterns: "*.conf"
|
|
recurse: false
|
|
register: server_confd_files
|
|
|
|
- name: Get checksums for all Git rsyslog.d files
|
|
stat:
|
|
path: "{{ item.path }}"
|
|
delegate_to: localhost
|
|
loop: "{{ git_confd_files.files }}"
|
|
register: git_confd_checksums
|
|
|
|
- name: Get checksums for all server rsyslog.d files
|
|
stat:
|
|
path: "{{ item.path }}"
|
|
loop: "{{ server_confd_files.files }}"
|
|
register: server_confd_checksums
|
|
|
|
- name: Compare rsyslog.d file checksums
|
|
set_fact:
|
|
rsyslogd_check:
|
|
changed: "{{ git_confd_checksums.results | map(attribute='stat.checksum') | list != server_confd_checksums.results | map(attribute='stat.checksum') | list }}"
|
|
|
|
- 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
|