fix: Use checksum-based content comparison to avoid permission-based drift false positives
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
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.
This commit is contained in:
parent
57870e65ce
commit
1cbe3d4de7
@ -94,7 +94,7 @@ steps:
|
|||||||
ANSIBLE_CONFIG: ansible.cfg
|
ANSIBLE_CONFIG: ansible.cfg
|
||||||
SSH_PRIVATE_KEY:
|
SSH_PRIVATE_KEY:
|
||||||
from_secret: SSH_PRIVATE_KEY
|
from_secret: SSH_PRIVATE_KEY
|
||||||
GITOPS_STATUS_SERVER_URL: http://gitops-status-server.observability-stack.svc.cluster.local:80
|
GITOPS_STATUS_SERVER_URL: http://gitops-status-api.observability-stack.svc.cluster.local:5000
|
||||||
REPO_NAME: rsyslog
|
REPO_NAME: rsyslog
|
||||||
SERVER_NAME: rsyslog-lab
|
SERVER_NAME: rsyslog-lab
|
||||||
# Optimize Ansible for container environment
|
# Optimize Ansible for container environment
|
||||||
@ -145,7 +145,7 @@ steps:
|
|||||||
ANSIBLE_CONFIG: ansible.cfg
|
ANSIBLE_CONFIG: ansible.cfg
|
||||||
SSH_PRIVATE_KEY:
|
SSH_PRIVATE_KEY:
|
||||||
from_secret: SSH_PRIVATE_KEY
|
from_secret: SSH_PRIVATE_KEY
|
||||||
GITOPS_STATUS_SERVER_URL: http://gitops-status-server.observability-stack.svc.cluster.local:80
|
GITOPS_STATUS_SERVER_URL: http://gitops-status-api.observability-stack.svc.cluster.local:5000
|
||||||
REPO_NAME: rsyslog
|
REPO_NAME: rsyslog
|
||||||
SERVER_NAME: rsyslog-lab
|
SERVER_NAME: rsyslog-lab
|
||||||
# Optimize Ansible for container environment
|
# Optimize Ansible for container environment
|
||||||
|
|||||||
@ -3,35 +3,69 @@
|
|||||||
hosts: rsyslog_servers
|
hosts: rsyslog_servers
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
|
|
||||||
# NOTE: src paths below resolve relative to the Ansible controller (the
|
# NOTE: This playbook compares file CONTENT ONLY using md5 checksums.
|
||||||
# Woodpecker CI container), so they always reflect the latest Git commit –
|
# It ignores permissions/ownership differences.
|
||||||
# NOT the server's local clone, which may be stale.
|
# Permissions are enforced during deploy (apply.yml)
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Use Ansible copy in check_mode so it compares controller files (Git)
|
# Checksum-based content comparison (ignores permissions/ownership)
|
||||||
# against live server files without actually writing anything.
|
# This is the only reliable way to detect actual config changes
|
||||||
# changed=true → file differs → drift
|
# after deployment when permissions have been set.
|
||||||
# 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
|
- name: Get MD5 checksum of Git version of rsyslog.conf
|
||||||
ansible.builtin.copy:
|
stat:
|
||||||
src: "{{ playbook_dir }}/../../files/rsyslog.d/"
|
path: "{{ playbook_dir }}/../../files/rsyslog.conf"
|
||||||
dest: "{{ rsyslog_config_dir }}/"
|
delegate_to: localhost
|
||||||
check_mode: true
|
register: git_rsyslog_conf_stat
|
||||||
diff: true
|
|
||||||
register: rsyslogd_check
|
- 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
|
- name: Check for extra files on server not present in Git
|
||||||
block:
|
block:
|
||||||
|
|||||||
@ -44,7 +44,7 @@ set -euo pipefail
|
|||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# Configuration
|
# Configuration
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
GITOPS_STATUS_SERVER_URL="${GITOPS_STATUS_SERVER_URL:-http://gitops-status-server.observability-stack.svc.cluster.local:80}"
|
GITOPS_STATUS_SERVER_URL="${GITOPS_STATUS_SERVER_URL:-http://gitops-status-api.observability-stack.svc.cluster.local:5000}"
|
||||||
REPO_NAME="${REPO_NAME:-rsyslog}"
|
REPO_NAME="${REPO_NAME:-rsyslog}"
|
||||||
SERVER_NAME="${SERVER_NAME:-rsyslog-lab}"
|
SERVER_NAME="${SERVER_NAME:-rsyslog-lab}"
|
||||||
INVENTORY_FILE="ansible/inventory/hosts.yml"
|
INVENTORY_FILE="ansible/inventory/hosts.yml"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user