Comprehensive security update automation: 1. Debian OS (unattended-upgrades) — tightened to security-only: - Removed general Debian updates (prevents feature/breaking changes) - Only Debian-Security origins auto-installed - Email admin on every upgrade via ops@performancewest.net - Auto-reboot at 4 AM if kernel update requires it - needrestart auto-restarts services after library updates 2. Docker CE — major version guard: - Patch updates within pinned major version auto-applied - Major version jumps held + admin alerted for manual review - docker-ce, docker-ce-cli, containerd.io all version-guarded 3. Container base images — daily at 3:30 AM: - Pulls latest base images for all docker-compose services - Compares image digests — only rebuilds if changed - Restarts only affected services (not full stack) - Alerts admin on rebuild failures requiring manual intervention - Covers both prod and dev compose projects 4. k3s — weekly Sunday at 3:45 AM: - Patch updates within current minor auto-applied - Minor/major upgrades alert admin for manual review - Verifies node Ready status after update - Alerts on failures with investigation instructions 5. Admin notifications via SMTP: - [INFO] for successful patches - [WARNING] for available major upgrades needing review - [CRITICAL] for failures requiring immediate intervention - Falls back to syslog if SMTP unavailable Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
122 lines
4.5 KiB
YAML
122 lines
4.5 KiB
YAML
---
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# Security Updates Role
|
|
#
|
|
# 1. Configures apt to allow Docker CE security patches (not major upgrades)
|
|
# 2. Deploys a container image update script (pulls new base images, rebuilds
|
|
# if changed, restarts affected services)
|
|
# 3. Deploys a k3s patch update script (stays on current channel, patch only)
|
|
# 4. Sets up systemd timers for all of the above
|
|
# 5. Sends admin email when manual intervention is required
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
# ── 1. Docker CE: pin major version, allow patch updates ────────────────────
|
|
|
|
- name: Install apt-mark hold for Docker CE (prevent major version jumps)
|
|
ansible.builtin.shell: |
|
|
current=$(dpkg-query -W -f='${Version}' docker-ce 2>/dev/null | grep -oP '^\d+' || echo "")
|
|
if [ -n "$current" ] && [ "$current" = "{{ docker_major_version_pin }}" ]; then
|
|
# Same major — ensure NOT held so patches flow through unattended-upgrades
|
|
apt-mark unhold docker-ce docker-ce-cli containerd.io 2>/dev/null || true
|
|
else
|
|
# Different major — hold to prevent auto-upgrade
|
|
apt-mark hold docker-ce docker-ce-cli containerd.io 2>/dev/null || true
|
|
fi
|
|
changed_when: false
|
|
|
|
- name: Deploy Docker version guard script
|
|
ansible.builtin.template:
|
|
src: docker-version-guard.sh.j2
|
|
dest: /usr/local/bin/pw-docker-version-guard
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
# ── 2. Container base image security updates ───────────────────────────────
|
|
|
|
- name: Deploy container image update script
|
|
ansible.builtin.template:
|
|
src: container-security-update.sh.j2
|
|
dest: /usr/local/bin/pw-container-security-update
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Deploy container update systemd service
|
|
ansible.builtin.template:
|
|
src: pw-container-update.service.j2
|
|
dest: /etc/systemd/system/pw-container-update.service
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify: Reload systemd
|
|
|
|
- name: Deploy container update systemd timer
|
|
ansible.builtin.template:
|
|
src: pw-container-update.timer.j2
|
|
dest: /etc/systemd/system/pw-container-update.timer
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify:
|
|
- Reload systemd
|
|
- Enable container update timer
|
|
|
|
# ── 3. k3s patch updates ───────────────────────────────────────────────────
|
|
|
|
- name: Deploy k3s patch update script
|
|
ansible.builtin.template:
|
|
src: k3s-security-update.sh.j2
|
|
dest: /usr/local/bin/pw-k3s-security-update
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Deploy k3s update systemd service
|
|
ansible.builtin.template:
|
|
src: pw-k3s-update.service.j2
|
|
dest: /etc/systemd/system/pw-k3s-update.service
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify: Reload systemd
|
|
|
|
- name: Deploy k3s update systemd timer
|
|
ansible.builtin.template:
|
|
src: pw-k3s-update.timer.j2
|
|
dest: /etc/systemd/system/pw-k3s-update.timer
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify:
|
|
- Reload systemd
|
|
- Enable k3s update timer
|
|
|
|
# ── 4. Admin alert helper ──────────────────────────────────────────────────
|
|
|
|
- name: Deploy admin alert script
|
|
ansible.builtin.template:
|
|
src: pw-security-alert.sh.j2
|
|
dest: /usr/local/bin/pw-security-alert
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
# ── 5. Ensure needrestart is installed for library/service detection ───────
|
|
|
|
- name: Install needrestart for detecting outdated services
|
|
ansible.builtin.apt:
|
|
name: needrestart
|
|
state: present
|
|
|
|
- name: Configure needrestart — auto-restart services, never interactive
|
|
ansible.builtin.copy:
|
|
content: |
|
|
# Auto-restart services after library updates (no prompts)
|
|
$nrconf{restart} = 'a';
|
|
# Don't restart these (handled by our own scripts)
|
|
$nrconf{blacklist_rc} = [qr(^docker), qr(^containerd), qr(^k3s)];
|
|
dest: /etc/needrestart/conf.d/pw-security.conf
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|