Rework portfolio around Linux operations, Zabbix monitoring, migration validation, and ELK/Grafana log observability. Add AAP-style LVM resize workflow, Zabbix server/proxy/agent automation assets, Linux/AIX monitoring templates, and updated validation CI.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# Patching Role
|
||||
|
||||
Apply security patches and OS updates to enterprise infrastructure nodes.
|
||||
|
||||
## Features
|
||||
|
||||
- **Idempotent**: Properly checks for changes with `changed_when`
|
||||
- **Patch Window**: Optional enforcement of patch time windows
|
||||
- **Pre-patch Backup**: Backs up package list before patching
|
||||
- **Smart Reboot**: Automatically detects if reboot is required
|
||||
- **Service Restart**: Restarts only necessary services after patching
|
||||
- **Health Checks**: Verifies services and runs health endpoint checks
|
||||
|
||||
## Role Variables
|
||||
|
||||
See `defaults/main.yml` for all available variables.
|
||||
|
||||
### Key Variables
|
||||
|
||||
- `patch_window_start`: Patch window start time (default: 02:00)
|
||||
- `patch_window_end`: Patch window end time (default: 04:00)
|
||||
- `enforce_patch_window`: Enforce patch time window (default: true)
|
||||
- `patch_security_only`: Apply security updates only (default: true)
|
||||
- `backup_before_patch`: Create backup before patching (default: true)
|
||||
- `reboot_if_required`: Auto-reboot if required (default: false)
|
||||
- `services_to_restart`: Services to restart after patching
|
||||
- `critical_services`: Critical services to verify after patching
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
- role: patching
|
||||
vars:
|
||||
patch_security_only: true
|
||||
enforce_patch_window: false
|
||||
reboot_if_required: true
|
||||
```
|
||||
|
||||
## Report
|
||||
|
||||
Patch report is generated at: `/var/log/patch_report_<timestamp>.log`
|
||||
|
||||
## Backup Location
|
||||
|
||||
Pre-patch backups saved to: `/var/backups/pre-patch-<timestamp>/`
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# Patching configuration
|
||||
patch_window_start: "02:00"
|
||||
patch_window_end: "04:00"
|
||||
enforce_patch_window: true
|
||||
patch_security_only: true
|
||||
backup_before_patch: true
|
||||
reboot_if_required: false
|
||||
reboot_timeout: 300
|
||||
|
||||
# Services to restart after patching
|
||||
services_to_restart:
|
||||
- sshd
|
||||
- fail2ban
|
||||
|
||||
# Services to verify after patching
|
||||
critical_services:
|
||||
- systemd-journald
|
||||
- systemd-logind
|
||||
- cron
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: restart patching services
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
loop: "{{ services_to_restart }}"
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
- name: Validate patch window
|
||||
when: enforce_patch_window | bool
|
||||
block:
|
||||
- name: Check current time against patch window
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_date_time.hour | int >= patch_window_start.split(':')[0] | int
|
||||
- ansible_date_time.hour | int < patch_window_end.split(':')[0] | int
|
||||
fail_msg: |
|
||||
Current time {{ ansible_date_time.hour }}:{{ ansible_date_time.minute }} is outside patch window {{ patch_window_start }}-{{ patch_window_end }}
|
||||
|
||||
- name: Create pre-patch backup
|
||||
when: backup_before_patch | bool
|
||||
block:
|
||||
- name: Create backup directory
|
||||
ansible.builtin.file:
|
||||
path: "/var/backups/pre-patch-{{ ansible_date_time.iso8601 }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Capture current package list
|
||||
ansible.builtin.shell: |
|
||||
set -o pipefail
|
||||
dpkg --get-selections > /var/backups/pre-patch-{{ ansible_date_time.iso8601 }}/packages.list
|
||||
changed_when: false
|
||||
|
||||
- name: Check for available updates
|
||||
ansible.builtin.shell: |
|
||||
set -o pipefail
|
||||
apt list --upgradable 2>/dev/null | grep -v "Listing..." | wc -l
|
||||
register: updates_available_count
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Update package cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 300
|
||||
changed_when: false
|
||||
|
||||
- name: Check if reboot required before patching
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required_before
|
||||
changed_when: false
|
||||
|
||||
- name: Apply security updates
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
update_cache: true
|
||||
when: patch_security_only | bool
|
||||
register: apt_update_result
|
||||
notify: restart patching services
|
||||
|
||||
- name: Apply all available updates
|
||||
ansible.builtin.apt:
|
||||
upgrade: full
|
||||
update_cache: true
|
||||
when: not (patch_security_only | bool)
|
||||
register: apt_update_result
|
||||
notify: restart patching services
|
||||
|
||||
- name: Check if reboot required after patching
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required_after
|
||||
changed_when: false
|
||||
|
||||
- name: Verify critical services are running
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
enabled: true
|
||||
loop: "{{ critical_services }}"
|
||||
failed_when: false
|
||||
|
||||
- name: Run post-patch health checks
|
||||
ansible.builtin.uri:
|
||||
url: http://localhost/health
|
||||
method: GET
|
||||
status_code: 200
|
||||
register: health_check
|
||||
failed_when: false
|
||||
ignore_errors: true
|
||||
when: "'webservers' in group_names"
|
||||
|
||||
- name: Set reboot required flag
|
||||
ansible.builtin.set_fact:
|
||||
reboot_required: "{{ reboot_required_after.stat.exists | default(false) }}"
|
||||
|
||||
- name: Perform system reboot if required
|
||||
ansible.builtin.reboot:
|
||||
msg: "Rebooting after security patches"
|
||||
timeout: "{{ reboot_timeout }}"
|
||||
when: reboot_required and reboot_if_required | bool
|
||||
|
||||
- name: Generate patching report
|
||||
ansible.builtin.template:
|
||||
src: patch_report.j2
|
||||
dest: /var/log/patch_report_{{ ansible_date_time.iso8601 }}.log
|
||||
mode: '0644'
|
||||
vars:
|
||||
updates_applied_count: "{{ apt_update_result.changed | ternary('Yes', 'No') }}"
|
||||
reboot_required_flag: "{{ reboot_required }}"
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
Patching Report
|
||||
===============
|
||||
Generated: {{ ansible_date_time.iso8601 }}
|
||||
Host: {{ inventory_hostname }}
|
||||
|
||||
Updates Applied: {{ updates_applied_count }}
|
||||
Reboot Required: {{ reboot_required_flag }}
|
||||
Services Restarted: {{ services_to_restart | join(', ') }}
|
||||
|
||||
Backup Location: /var/backups/pre-patch-{{ ansible_date_time.iso8601 }}/
|
||||
Reference in New Issue
Block a user