Skip to main content
RunBook Academy

LinuxXXXIII · Fleet Patch ManagementValidation

Pre-patching and post-patching validation

Intermediate⏱ ~10 mincurlmonitoringautomation

What you'll learn

  • Validate before patching
  • Run health checks during patching
  • Verify post-patching state
  • Define rollback triggers

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

A patch is not done when the package is installed; it is done when the service is verified to work. Validation is the critical step.

Before patching

# Substitute your own values before running:
SERVICE=nginx

# Snapshot the baseline
curl -I https://host/health > /tmp/baseline-health.txt
curl -s https://host/metrics > /tmp/baseline-metrics.txt
sudo systemctl status "$SERVICE" > /tmp/baseline-status.txt

# Document the current state
echo "Pre-patch state captured at $(date)"

During patching

Watch:

  • Service is responding (curl -I https://host/).
  • Error rate (HTTP 5xx, application errors).
  • Latency (p99, p95, p50).
  • Resource usage (CPU, memory, disk, network).
  • Process count (correct number of workers).

Automate with synthetic monitoring:

# Every 30 seconds for 5 minutes after the patch
for i in {1..10}; do
    STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://host/)
    if [ "$STATUS" != "200" ]; then
        echo "FAIL at iteration $i: $STATUS"
        # Roll back
        break
    fi
    sleep 30
done

After patching

# Verify the same endpoints
curl -I https://host/health
curl -I https://host/api/v1/status

# Verify CVE is patched
trivy fs /
oscap xccdf eval --profile standard /usr/share/xml/scap/content/ssg-*.xml

# Verify no new errors
journalctl --since "1 hour ago" -p err

Rollback triggers

Define explicit triggers that mean “stop the rollout”:

  • Error rate > 1% sustained.
  • p99 latency > 2x baseline.
  • CPU > 90% sustained.
  • Service not responding (health check fails 3 times in a row).

Automated:

# Stop deployment if metrics exceed threshold
ERROR_RATE=$(curl -s "http://prometheus/api/v1/query?query=rate(http_requests_total{status=~'5..'}[5m])" | jq .data.result[0].value[1])

if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then
    echo "Error rate too high: $ERROR_RATE"
    exit 1    # Ansible stops, manual decision
fi

Document the validation

PATCH VALIDATION
================
Host: web01
Date: 2026-08-09
Patch: nginx 1.27.2

Pre-patch:
- Health: 200
- p99 latency: 45ms
- Error rate: 0.001

Post-patch:
- Health: 200
- p99 latency: 47ms (within 10% of baseline)
- Error rate: 0.001
- CVE-2024-XXXXX: not detected by trivy

Validation: PASS
Approved by: on-call

Knowledge check

Knowledge check · 3 questions

  1. Q1. When should rollback triggers be defined?

  2. Q2. A patch is done when the package is installed.

  3. Q3. Which of the following are valid post-patch validations? Select all that apply.

Passing score: 75%. Answers are checked in this browser.