mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
499 lines
12 KiB
Markdown
499 lines
12 KiB
Markdown
---
|
|
name: alerting-oncall
|
|
description: Set up alerting rules, configure on-call rotations, and manage incident response workflows. Integrate with PagerDuty, Opsgenie, or Grafana OnCall for alert routing and escalation. Use when implementing alerting strategies and on-call management for production systems.
|
|
license: MIT
|
|
metadata:
|
|
author: devops-skills
|
|
version: "1.0"
|
|
---
|
|
|
|
# Alerting & On-Call
|
|
|
|
Configure effective alerting and on-call management for production systems.
|
|
|
|
## When to Use This Skill
|
|
|
|
Use this skill when:
|
|
- Setting up alerting rules and thresholds
|
|
- Configuring on-call rotations and schedules
|
|
- Implementing alert routing and escalation
|
|
- Reducing alert fatigue
|
|
- Managing incident response workflows
|
|
|
|
## Prerequisites
|
|
|
|
- Monitoring system (Prometheus, Datadog, etc.)
|
|
- On-call platform (PagerDuty, Opsgenie, Grafana OnCall)
|
|
- Communication channels (Slack, email)
|
|
|
|
## Alerting Best Practices
|
|
|
|
### Alert Categories
|
|
|
|
```yaml
|
|
# Severity levels
|
|
critical:
|
|
- Service completely down
|
|
- Data loss imminent
|
|
- Security breach
|
|
response: Immediate page, wake people up
|
|
|
|
high:
|
|
- Service degraded significantly
|
|
- Error rate above SLO
|
|
- Capacity near limit
|
|
response: Page during business hours, notify after hours
|
|
|
|
medium:
|
|
- Performance degradation
|
|
- Non-critical component failure
|
|
- Warning thresholds exceeded
|
|
response: Notify via Slack, review next business day
|
|
|
|
low:
|
|
- Informational alerts
|
|
- Capacity planning triggers
|
|
- Routine maintenance needed
|
|
response: Email notification, weekly review
|
|
```
|
|
|
|
### Alert Design Principles
|
|
|
|
```yaml
|
|
# Good alert characteristics
|
|
alerts:
|
|
actionable:
|
|
- Every alert should require human action
|
|
- Include runbook links
|
|
- Clear remediation steps
|
|
|
|
relevant:
|
|
- Alert on symptoms, not causes
|
|
- Focus on user impact
|
|
- Avoid alerting on expected behavior
|
|
|
|
timely:
|
|
- Appropriate thresholds
|
|
- Suitable evaluation windows
|
|
- Account for normal variance
|
|
|
|
unique:
|
|
- No duplicate alerts
|
|
- Proper alert grouping
|
|
- Clear ownership
|
|
```
|
|
|
|
## Prometheus Alerting
|
|
|
|
### Alert Rules
|
|
|
|
```yaml
|
|
# prometheus/rules/alerts.yml
|
|
groups:
|
|
- name: service_alerts
|
|
rules:
|
|
# High-level service health
|
|
- alert: ServiceDown
|
|
expr: up{job="myapp"} == 0
|
|
for: 1m
|
|
labels:
|
|
severity: critical
|
|
annotations:
|
|
summary: "Service {{ $labels.instance }} is down"
|
|
description: "{{ $labels.job }} on {{ $labels.instance }} has been down for more than 1 minute."
|
|
runbook_url: "https://wiki.example.com/runbooks/service-down"
|
|
|
|
# Error rate alert
|
|
- alert: HighErrorRate
|
|
expr: |
|
|
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
|
|
/ sum(rate(http_requests_total[5m])) by (service) > 0.05
|
|
for: 5m
|
|
labels:
|
|
severity: critical
|
|
annotations:
|
|
summary: "High error rate for {{ $labels.service }}"
|
|
description: "Error rate is {{ $value | humanizePercentage }} for the last 5 minutes"
|
|
|
|
# Latency alert (SLO-based)
|
|
- alert: HighLatency
|
|
expr: |
|
|
histogram_quantile(0.95,
|
|
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
|
|
) > 0.5
|
|
for: 5m
|
|
labels:
|
|
severity: high
|
|
annotations:
|
|
summary: "P95 latency above 500ms for {{ $labels.service }}"
|
|
```
|
|
|
|
### Alertmanager Configuration
|
|
|
|
```yaml
|
|
# alertmanager.yml
|
|
global:
|
|
resolve_timeout: 5m
|
|
slack_api_url: 'https://hooks.slack.com/services/xxx'
|
|
pagerduty_url: 'https://events.pagerduty.com/v2/enqueue'
|
|
|
|
templates:
|
|
- '/etc/alertmanager/templates/*.tmpl'
|
|
|
|
route:
|
|
receiver: 'default-receiver'
|
|
group_by: ['alertname', 'service']
|
|
group_wait: 30s
|
|
group_interval: 5m
|
|
repeat_interval: 4h
|
|
|
|
routes:
|
|
# Critical alerts go to PagerDuty
|
|
- match:
|
|
severity: critical
|
|
receiver: 'pagerduty-critical'
|
|
group_wait: 0s
|
|
repeat_interval: 1h
|
|
|
|
# High severity during business hours
|
|
- match:
|
|
severity: high
|
|
receiver: 'slack-high'
|
|
active_time_intervals:
|
|
- business-hours
|
|
|
|
# Route by team
|
|
- match_re:
|
|
team: platform.*
|
|
receiver: 'platform-team'
|
|
|
|
receivers:
|
|
- name: 'default-receiver'
|
|
slack_configs:
|
|
- channel: '#alerts'
|
|
send_resolved: true
|
|
|
|
- name: 'pagerduty-critical'
|
|
pagerduty_configs:
|
|
- service_key: 'xxx'
|
|
severity: critical
|
|
description: '{{ .CommonAnnotations.summary }}'
|
|
details:
|
|
firing: '{{ template "pagerduty.firing" . }}'
|
|
|
|
- name: 'slack-high'
|
|
slack_configs:
|
|
- channel: '#alerts-high'
|
|
title: '{{ .CommonAnnotations.summary }}'
|
|
text: '{{ .CommonAnnotations.description }}'
|
|
actions:
|
|
- type: button
|
|
text: 'Runbook'
|
|
url: '{{ .CommonAnnotations.runbook_url }}'
|
|
- type: button
|
|
text: 'Dashboard'
|
|
url: '{{ .CommonAnnotations.dashboard_url }}'
|
|
|
|
- name: 'platform-team'
|
|
slack_configs:
|
|
- channel: '#platform-alerts'
|
|
|
|
time_intervals:
|
|
- name: business-hours
|
|
time_intervals:
|
|
- weekdays: ['monday:friday']
|
|
times:
|
|
- start_time: '09:00'
|
|
end_time: '17:00'
|
|
|
|
inhibit_rules:
|
|
- source_match:
|
|
severity: critical
|
|
target_match:
|
|
severity: high
|
|
equal: ['service']
|
|
```
|
|
|
|
## PagerDuty Integration
|
|
|
|
### Service Configuration
|
|
|
|
```yaml
|
|
# Terraform example
|
|
resource "pagerduty_service" "myapp" {
|
|
name = "MyApp Production"
|
|
description = "Production application service"
|
|
escalation_policy = pagerduty_escalation_policy.default.id
|
|
alert_creation = "create_alerts_and_incidents"
|
|
auto_resolve_timeout = 14400 # 4 hours
|
|
acknowledgement_timeout = 600 # 10 minutes
|
|
|
|
incident_urgency_rule {
|
|
type = "use_support_hours"
|
|
|
|
during_support_hours {
|
|
type = "constant"
|
|
urgency = "high"
|
|
}
|
|
|
|
outside_support_hours {
|
|
type = "constant"
|
|
urgency = "low"
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "pagerduty_escalation_policy" "default" {
|
|
name = "Default Escalation"
|
|
num_loops = 2
|
|
|
|
rule {
|
|
escalation_delay_in_minutes = 10
|
|
target {
|
|
type = "schedule_reference"
|
|
id = pagerduty_schedule.primary.id
|
|
}
|
|
}
|
|
|
|
rule {
|
|
escalation_delay_in_minutes = 15
|
|
target {
|
|
type = "user_reference"
|
|
id = pagerduty_user.manager.id
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Schedule Configuration
|
|
|
|
```yaml
|
|
resource "pagerduty_schedule" "primary" {
|
|
name = "Primary On-Call"
|
|
time_zone = "America/New_York"
|
|
|
|
layer {
|
|
name = "Weekly Rotation"
|
|
start = "2024-01-01T00:00:00-05:00"
|
|
rotation_virtual_start = "2024-01-01T00:00:00-05:00"
|
|
rotation_turn_length_seconds = 604800 # 1 week
|
|
users = [for user in pagerduty_user.oncall : user.id]
|
|
}
|
|
|
|
# Override layer for holidays
|
|
layer {
|
|
name = "Holiday Coverage"
|
|
start = "2024-01-01T00:00:00-05:00"
|
|
rotation_virtual_start = "2024-01-01T00:00:00-05:00"
|
|
rotation_turn_length_seconds = 86400
|
|
users = [pagerduty_user.holiday_coverage.id]
|
|
|
|
restriction {
|
|
type = "daily_restriction"
|
|
start_time_of_day = "00:00:00"
|
|
duration_seconds = 86400
|
|
start_day_of_week = 0 # Sunday
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Grafana OnCall
|
|
|
|
### Integration Setup
|
|
|
|
```yaml
|
|
# docker-compose.yml addition
|
|
services:
|
|
oncall:
|
|
image: grafana/oncall
|
|
environment:
|
|
- SECRET_KEY=your-secret-key
|
|
- BASE_URL=http://oncall:8080
|
|
- GRAFANA_API_URL=http://grafana:3000
|
|
ports:
|
|
- "8080:8080"
|
|
```
|
|
|
|
### Escalation Chain
|
|
|
|
```yaml
|
|
# Example escalation chain structure
|
|
escalation_chains:
|
|
- name: "Production Critical"
|
|
steps:
|
|
- step: 1
|
|
type: notify
|
|
persons:
|
|
- "@oncall-primary"
|
|
wait_delay: 0
|
|
|
|
- step: 2
|
|
type: notify
|
|
persons:
|
|
- "@oncall-secondary"
|
|
wait_delay: 5m
|
|
|
|
- step: 3
|
|
type: notify
|
|
persons:
|
|
- "@engineering-manager"
|
|
wait_delay: 10m
|
|
|
|
- step: 4
|
|
type: trigger_action
|
|
action: "escalate_to_incident_commander"
|
|
wait_delay: 15m
|
|
```
|
|
|
|
## Alert Templates
|
|
|
|
### Slack Alert Template
|
|
|
|
```go
|
|
{{ define "slack.title" }}
|
|
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }}
|
|
{{ end }}
|
|
|
|
{{ define "slack.text" }}
|
|
{{ range .Alerts }}
|
|
*Alert:* {{ .Annotations.summary }}
|
|
*Severity:* {{ .Labels.severity }}
|
|
*Description:* {{ .Annotations.description }}
|
|
*Runbook:* {{ .Annotations.runbook_url }}
|
|
{{ end }}
|
|
{{ end }}
|
|
```
|
|
|
|
### PagerDuty Details Template
|
|
|
|
```go
|
|
{{ define "pagerduty.firing" }}
|
|
{{ range .Alerts.Firing }}
|
|
Alert: {{ .Labels.alertname }}
|
|
Service: {{ .Labels.service }}
|
|
Instance: {{ .Labels.instance }}
|
|
Value: {{ .Annotations.value }}
|
|
Started: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
|
|
{{ end }}
|
|
{{ end }}
|
|
```
|
|
|
|
## On-Call Best Practices
|
|
|
|
### Rotation Guidelines
|
|
|
|
```yaml
|
|
on_call_guidelines:
|
|
rotation_length: 1 week
|
|
handoff_time: "10:00 AM Monday"
|
|
|
|
responsibilities:
|
|
- Monitor alerts during shift
|
|
- Respond within SLA (critical: 5min, high: 15min)
|
|
- Document incidents
|
|
- Handoff unresolved issues
|
|
|
|
support:
|
|
- Secondary on-call for backup
|
|
- Clear escalation path
|
|
- Manager availability for major incidents
|
|
|
|
wellness:
|
|
- Maximum 1 week on-call per month
|
|
- Comp time after high-alert periods
|
|
- No-interrupt recovery day after shift
|
|
```
|
|
|
|
### Runbook Template
|
|
|
|
```markdown
|
|
# Alert: High Error Rate
|
|
|
|
## Summary
|
|
Error rate has exceeded the threshold of 5% for the service.
|
|
|
|
## Impact
|
|
Users may experience errors when accessing the application.
|
|
|
|
## Investigation Steps
|
|
1. Check service logs: `kubectl logs -l app=myapp -n production`
|
|
2. Review recent deployments: `kubectl rollout history deployment/myapp`
|
|
3. Check database connectivity: `kubectl exec -it myapp -- nc -zv postgres 5432`
|
|
4. Review error traces in APM dashboard
|
|
|
|
## Remediation
|
|
### If caused by recent deployment:
|
|
```bash
|
|
kubectl rollout undo deployment/myapp -n production
|
|
```
|
|
|
|
### If database related:
|
|
```bash
|
|
kubectl delete pod -l app=postgres -n production
|
|
```
|
|
|
|
## Escalation
|
|
If not resolved within 15 minutes, escalate to:
|
|
- Database team: @db-oncall
|
|
- Platform team: @platform-oncall
|
|
```
|
|
|
|
## Alert Fatigue Reduction
|
|
|
|
### Strategies
|
|
|
|
```yaml
|
|
fatigue_reduction:
|
|
aggregate_alerts:
|
|
- Group related alerts
|
|
- Use inhibit rules
|
|
- Implement alert correlation
|
|
|
|
tune_thresholds:
|
|
- Base on SLOs, not arbitrary values
|
|
- Account for normal variance
|
|
- Use appropriate evaluation windows
|
|
|
|
automate_responses:
|
|
- Auto-remediation for known issues
|
|
- Self-healing infrastructure
|
|
- Automated scaling
|
|
|
|
regular_review:
|
|
- Weekly alert review
|
|
- Remove unused alerts
|
|
- Update thresholds based on data
|
|
```
|
|
|
|
## Common Issues
|
|
|
|
### Issue: Alert Storm
|
|
**Problem**: Too many alerts firing simultaneously
|
|
**Solution**: Implement proper grouping and inhibition rules
|
|
|
|
### Issue: Missed Alerts
|
|
**Problem**: Critical alerts not reaching on-call
|
|
**Solution**: Test escalation policies, verify contact methods
|
|
|
|
### Issue: False Positives
|
|
**Problem**: Alerts firing without actual issues
|
|
**Solution**: Tune thresholds, increase evaluation windows
|
|
|
|
## Best Practices
|
|
|
|
- Define clear severity levels
|
|
- Every alert needs a runbook
|
|
- Test on-call notifications regularly
|
|
- Review and tune alerts weekly
|
|
- Implement proper escalation paths
|
|
- Use alert grouping and inhibition
|
|
- Track alert metrics (MTTR, frequency)
|
|
- Practice incident response regularly
|
|
|
|
## Related Skills
|
|
|
|
- [prometheus-grafana](../prometheus-grafana/) - Monitoring setup
|
|
- [incident-response](../../../security/operations/incident-response/) - Incident handling
|
|
- [runbook-automation](../../../compliance/continuity/runbook-automation/) - Runbook creation
|