Ένα incident runbook είναι ένα σύντομο έγγραφο, συμφωνημένο από πριν, που απαντά σε τρεις ερωτήσεις υπό πίεση: πόσο σοβαρό είναι, ποιος κάνει τι, και τι κάνουμε τα επόμενα δεκαπέντε λεπτά. Αν θέλει πάνω από ένα λεπτό για να το βρείτε ή να το διαβάσετε, δεν θα το χρησιμοποιήσει κανείς.
Παρακάτω είναι το πρότυπο που δίνουμε σε μικρές ομάδες. Αντιγράψτε το στο wiki ή στο repo σας, αλλάξτε τις τιμές σε αγκύλες και βάλτε link σε αυτό σε κάθε alert. Μετά μιλάμε για τα δύο πράγματα που κρίνουν αν θα δουλέψει στην πράξη: ένα on-call που αντέχεται και alerts που ξυπνούν κάποιον μόνο για όσα νιώθουν οι χρήστες.
Το πρότυπο runbook
Επικολλήστε το όπως είναι και προσαρμόστε το. Οι αριθμοί μέσα (χρόνοι απόκρισης, συχνότητα ενημερώσεων) είναι λογικά σημεία εκκίνησης, όχι πρότυπα· αλλάξτε τους ώστε να ταιριάζουν με όσα υπόσχεστε στους πελάτες. Το κρατάμε στα αγγλικά, γιατί έτσι το διαβάζουν συνήθως όλοι στην ομάδα, αλλά μεταφράστε το ελεύθερα.
INCIDENT RESPONSE RUNBOOK - [Company]
Owner: [name] Last reviewed: [date]
Incident channel prefix: #inc- Status page: [URL]
1. SEVERITY LEVELS (if unsure, pick the higher one; downgrade later)
SEV1 Product down or unusable for most customers, data loss,
or confirmed security breach. Page 24/7. All hands.
SEV2 Core feature broken or badly degraded for many customers,
no workaround. Page 24/7.
SEV3 Partial or minor impact, workaround exists, single customer,
or internal tooling. Business hours only.
2. ROLES
Incident commander (IC) Owns the incident. Coordinates, decides,
keeps time. Does not debug.
Responder(s) Investigate and fix. Report to the IC.
Comms lead Status page, customer emails, support team,
management. Uses templates in section 4.
Scribe Timeline in the incident channel (UTC).
Small team rule: for SEV3 one person can hold every role. For SEV1
the IC is never the person typing commands into production.
3. FIRST 15 MINUTES
[ ] Acknowledge the page.
[ ] Open #inc-[yyyymmdd]-[short-name], post the alert and this runbook.
[ ] Declare: "I am IC. This is SEV[n]. Impact so far: [...]"
[ ] What changed? Last deploys, feature flags, config, Terraform
applies, cron jobs, AWS Health Dashboard, third-party status pages.
[ ] How big is it? Error rate, latency, traffic dashboards, support inbox.
[ ] Decide: roll back / mitigate / keep investigating (section 6).
[ ] SEV1-2: assign a comms lead, first status page update.
[ ] Security suspected? Preserve evidence (snapshot, don't terminate),
revoke exposed credentials, go to section 8.
4. COMMUNICATION
Internal update, every 30 min (SEV1) or 60 min (SEV2):
Status: investigating | identified | monitoring | resolved
Impact: [who and what is affected]
Actions: [what we are doing now]
Next update: [HH:MM UTC]
Customer update - investigating:
"We are investigating [elevated errors / slow responses] affecting
[feature]. Some customers may be unable to [action]. We will post
an update by [HH:MM UTC]."
Customer update - identified:
"We have identified the cause of [issue] and are [rolling back a
recent change / applying a fix]. [Feature] may remain [degraded]
until then. Next update by [HH:MM UTC]."
Customer update - resolved:
"[Feature] has been working normally since [HH:MM UTC]. Between
[start] and [end], [describe impact]. We are reviewing what
happened and will share a summary by [date]."
5. ESCALATION
No acknowledgement in [5] min -> page secondary
No acknowledgement in [15] min -> call [engineering lead], [phone]
Escalate to [CTO / founder] when: SEV1, suspected data loss or breach,
contractual SLA at risk, or no mitigation after [60] min.
Vendors: AWS Support (case severity per your support plan),
[payment provider], [DNS / CDN], [other] - contacts: [link]
6. ROLLBACK DECISION
Roll back first, debug later, when:
- the incident started within [2] hours of a deploy, flag or
config change, AND
- the rollback is known to be safe (no irreversible migration).
Do not roll back blindly when:
- a database migration is not backward compatible -> forward fix
or restore plan, IC decides
- the cause is external (AWS, a vendor) -> mitigate: fail over,
disable the feature, degrade gracefully
Time-box investigation to [15] min before choosing a mitigation.
7. RESOLUTION
[ ] Impact gone and stable for [30] min.
[ ] Final internal and customer updates sent.
[ ] Post-incident review created, owner assigned, due in [5]
working days.
[ ] Summary pinned in the channel, channel archived.
8. SECURITY AND REGULATORY
[ ] Personal data affected? -> [DPO]. GDPR: notify the supervisory
authority within 72 hours of becoming aware, where feasible.
[ ] In scope for NIS2 and the incident may be significant?
-> [named person] decides. Early warning within 24 hours,
incident notification within 72 hours, final report within
one month.
[ ] Customer contracts with notification clauses? -> [owner]
9. CONTACTS
Role Name Phone Backup
Engineering lead [...] [...] [...]
CTO / founder [...] [...] [...]
DPO / legal [...] [...] [...]
Επίπεδα σοβαρότητας: με βάση την επίπτωση, όχι την αιτία
Η σοβαρότητα πρέπει να περιγράφει τι ζουν οι πελάτες, ώστε οποιοσδήποτε στην ομάδα να τη διαλέξει σε δευτερόλεπτα χωρίς να ξέρει τη ρίζα του προβλήματος. Τρία επίπεδα φτάνουν για μια μικρή ομάδα· ένα τέταρτο συνήθως γίνεται το μέρος όπου κρύβονται πράγματα.
Η σοβαρότητα καθορίζει τρία πράγματα: αν θα ξυπνήσει κάποιος, πόσο συχνά ενημερώνετε, και ποιος μαθαίνει τι συμβαίνει. Κρατήστε το τόσο απλό. Αν ένα incident χρειάζεται συζήτηση για τη σοβαρότητα, διαλέξτε την υψηλότερη και προχωρήστε.
Ρόλοι: γιατί ο incident commander δεν κάνει debug
Ο incident commander συντονίζει και αποφασίζει· οι responders διορθώνουν. Ο διαχωρισμός αυτός είναι η πιο αποτελεσματική συνήθεια που βλέπουμε σε μικρές ομάδες, γιατί όποιος είναι χωμένος σε ένα stack trace δεν μπορεί ταυτόχρονα να μετρά τον χρόνο, να προσέξει ότι κανείς δεν ενημέρωσε το status page ή να ζητήσει βοήθεια.
Οι ρόλοι ακολουθούν το μοντέλο incident command που έκανε γνωστό η ανοιχτή τεκμηρίωση incident response της PagerDuty, που αξίζει να τη διαβάσετε ολόκληρη. Σε μια ομάδα πέντε ατόμων, IC είναι συχνά ο engineering lead ή όποιος έχει secondary. Οι ρόλοι είναι καπέλα, όχι τίτλοι: ο ίδιος άνθρωπος μπορεί να είναι scribe τη μία εβδομάδα και IC την επόμενη.
Ο κανόνας του rollback
Αν κάτι χάλασε λίγο μετά από μια αλλαγή και το rollback είναι ασφαλές, κάντε πρώτα rollback και ψάξτε μετά. Τα περισσότερα incidents σε μικρές ομάδες έρχονται μετά από ένα deploy, μια αλλαγή config ή ένα feature flag, και η επαναφορά της υπηρεσίας αξίζει περισσότερο από το να καταλάβετε το bug δέκα λεπτά νωρίτερα.
Αυτό δουλεύει μόνο αν το rollback είναι βαρετό. Immutable image tags, redeploy της προηγούμενης έκδοσης με ένα κλικ και migrations συμβατά προς τα πίσω είναι προϋποθέσεις· για το πρώτο γράψαμε στο σταματήστε να κάνετε deploy το latest tag στο Kubernetes, και για συνήθειες στο pipeline που δυσκολεύουν το rollback στα CI/CD anti-patterns.
Πρότυπο post-incident review (blameless)
Ένα blameless review ρωτά τι στο σύστημα επέτρεψε την αστοχία, όχι ποιος φταίει. Όσοι περιμένουν να κατηγορηθούν κρύβουν λεπτομέρειες, και οι λεπτομέρειες είναι αυτό που χρειάζεστε για να μην ξανασυμβεί. Κάντε το review μέσα σε μία εβδομάδα, όσο οι μνήμες είναι φρέσκες.
POST-INCIDENT REVIEW - [title]
Date: [yyyy-mm-dd] Severity: SEV[n] IC: [name] Author: [name]
Status: draft | reviewed | actions complete
SUMMARY (3 sentences)
What happened, who was affected, how it was resolved.
IMPACT
Duration (start -> detected -> mitigated -> resolved, UTC):
Customers / requests affected:
Data loss or exposure: yes / no (details)
SLA or regulatory implications:
TIMELINE (UTC)
[hh:mm] [event - from the incident channel]
CONTRIBUTING FACTORS
Technical: [what failed and why it was possible]
Detection: [how we found out; could we have known sooner?]
Process: [what slowed the response]
(Describe systems and decisions, never individuals' mistakes.)
WHAT WENT WELL
[...]
WHERE WE GOT LUCKY
[...]
ACTION ITEMS
Action Owner Ticket Due
[prevent recurrence] [...] [...] [...]
[detect faster] [...] [...] [...]
[respond faster / runbook fix] [...] [...] [...]
Δύο κανόνες κάνουν τα reviews χρήσιμα. Κάθε action item έχει owner και ticket, αλλιώς δεν μπαίνει. Και το «να είμαστε πιο προσεκτικοί» δεν είναι ποτέ action item· αν ένας άνθρωπος μπορεί να κάνει το λάθος, η λύση είναι ένα guardrail, ένα test ή ένα alert.
On-call για ομάδα 3 έως 10 ατόμων
Σε μικρή ομάδα, ένα on-call που αντέχεται κρίνεται από δύο πράγματα: να μοιράζεται το βάρος δίκαια, και να είναι λίγα τα pages εκτός ωραρίου. Το πρώτο το λύνει η σωστή rotation· το δεύτερο μόνο η ποιότητα των alerts.
- Εβδομαδιαία rotation, παράδοση μέσα στην εβδομάδα. Με παράδοση Τρίτη ή Τετάρτη, κανείς δεν ξεκινά βάρδια Παρασκευή βράδυ, και η παράδοση γίνεται όταν είναι όλοι διαθέσιμοι.
- Με 3 ή 4 engineers: ένας primary, και ο engineering lead ή ο CTO ως σημείο κλιμάκωσης. Εκτός ωραρίου, page μόνο για SEV1 και SEV2.
- Από περίπου 5 engineers: προσθέστε secondary, που παίρνει το page αν ο primary δεν απαντήσει και γίνεται IC στα μεγαλύτερα incidents.
- Αμείψτε το. Επίδομα on-call ή ρεπό, και μετά από νυχτερινό page ο on-call ξεκινά αργότερα την επόμενη μέρα. Ελέγξτε τι προβλέπουν η εργατική νομοθεσία και οι συμβάσεις· στην Ελλάδα και σε μεγάλο μέρος της ΕΕ ισχύουν κανόνες για ετοιμότητα και υπερωρίες.
- Shadowing πριν από τη μόνη βάρδια. Οι νέοι engineers κάνουν μία rotation μαζί με τον primary πριν πάρουν μόνοι τους το pager.
- Κάθε alert έχει link σε runbook. Όποιος ξυπνήσει δεν πρέπει ποτέ να μαντεύει τι σημαίνει ένα alert.
- Review των pages κάθε εβδομάδα. Περάστε κάθε page της προηγούμενης εβδομάδας: ήταν πραγματικό, μπορούσε κανείς να κάνει κάτι, χρειαζόταν άνθρωπο εκείνη την ώρα; Ό,τι αποτυγχάνει, το σβήνετε, το υποβιβάζετε ή το διορθώνετε.
Αντιμετωπίστε τα pages εκτός ωραρίου ως μετρική. Αν κάποιος πέρασε δύσκολη εβδομάδα, το επόμενο sprint πρέπει να περιλαμβάνει τη διόρθωση των αιτιών, όχι μόνο ένα ευχαριστώ. Το κεφάλαιο για το on-call στο SRE book της Google μπαίνει πιο βαθιά στην ισορροπία φόρτου και ποιότητας.
Alerting που ξυπνά κάποιον μόνο για όσα βλέπουν οι χρήστες
Κάντε page για συμπτώματα που νιώθουν οι χρήστες, όπως errors, latency και αποτυχίες σε βασικές ροές, και στείλτε όλα τα υπόλοιπα σε ticket ή dashboard. Ένα υψηλό CPU σε ένα node στις 3 το πρωί δεν αξίζει να ξυπνήσει κανέναν αν οι χρήστες δεν επηρεάζονται· ένα error rate που ανεβαίνει αξίζει, όποια κι αν είναι η αιτία.
Αυτή είναι η προσέγγιση του κεφαλαίου για το monitoring στο SRE book της Google: παρακολουθείτε τα four golden signals (latency, traffic, errors, saturation) και κρατάτε τα pages για προβλήματα επείγοντα, ορατά στους χρήστες και που μπορεί κάποιος να κάνει κάτι γι' αυτά. Στην πράξη, για μια τυπική web υπηρεσία στο AWS:
- Page: ποσοστό 5xx πάνω από το όριο για αρκετά λεπτά, p99 latency πάνω από το όριο, synthetic check σε login ή checkout που αποτυγχάνει από περισσότερες από μία τοποθεσίες, ουρά που μεγαλώνει πέρα από όσο θα πρόσεχαν οι χρήστες.
- Ticket, όχι page: δίσκος που γεμίζει αργά, πιστοποιητικό που λήγει σε δύο εβδομάδες, ένα unhealthy instance πίσω από load balancer, υψηλό CPU χωρίς επίπτωση στους χρήστες.
Ορίστε ένα CloudWatch alarm στο ποσοστό 5xx του ALB αντί για σκέτο αριθμό errors, ώστε να κλιμακώνεται με την κίνηση και να αγνοεί τις ήσυχες ώρες. Τα όρια είναι παραδείγματα· ρυθμίστε τα με βάση τη δική σας κανονική συμπεριφορά.
resource "aws_cloudwatch_metric_alarm" "api_5xx_ratio" {
alarm_name = "api-5xx-ratio-high"
alarm_description = "SEV2: API 5xx ratio above 2%. Runbook: [wiki link]"
comparison_operator = "GreaterThanThreshold"
threshold = 2
evaluation_periods = 5
datapoints_to_alarm = 3
treat_missing_data = "notBreaching"
alarm_actions = [aws_sns_topic.pager.arn]
ok_actions = [aws_sns_topic.pager.arn]
metric_query {
id = "ratio"
expression = "IF(requests > 50, 100 * FILL(errors, 0) / requests, 0)"
label = "5xx %"
return_data = true
}
metric_query {
id = "errors"
metric {
namespace = "AWS/ApplicationELB"
metric_name = "HTTPCode_Target_5XX_Count"
period = 60
stat = "Sum"
dimensions = { LoadBalancer = aws_lb.api.arn_suffix }
}
}
metric_query {
id = "requests"
metric {
namespace = "AWS/ApplicationELB"
metric_name = "RequestCount"
period = 60
stat = "Sum"
dimensions = { LoadBalancer = aws_lb.api.arn_suffix }
}
}
}
Συνδέστε το SNS topic με το εργαλείο paging που χρησιμοποιείτε (PagerDuty, incident.io και τα αντίστοιχα το δέχονται όλα). Βάλτε το link του runbook στο description του alarm, ώστε να φτάνει μαζί με το page.
NIS2 και αναφορά incidents
Αν η εταιρεία σας εμπίπτει στην NIS2, ένα σημαντικό incident ενεργοποιεί προθεσμίες αναφοράς: έγκαιρη προειδοποίηση μέσα σε 24 ώρες, κοινοποίηση του incident μέσα σε 72 ώρες και τελική αναφορά μέσα σε έναν μήνα, όπως ορίζει το άρθρο 23 της οδηγίας. Η ενότητα 8 του προτύπου υπάρχει ώστε ένας συγκεκριμένος άνθρωπος να πάρει αυτή την απόφαση κατά τη διάρκεια του incident, όχι μέρες μετά. Το checklist για NIS2 στο AWS εξηγεί τι χρειάζεται η αναφορά και πώς την εφαρμόζει ο ν. 5160/2024. Το ίδιο αρχείο incidents και reviews χρησιμεύει και ως στοιχείο για έναν έλεγχο SOC 2.
Κάντε το πραγματικό με μια άσκηση
Ένα runbook που δεν έχει χρησιμοποιήσει κανείς είναι ακόμη πρόχειρο. Μία φορά το τρίμηνο, κάντε ένα game day μισής ώρας: κάποιος χαλάει κάτι στο staging, ο on-call ακολουθεί το runbook, και η ομάδα διορθώνει ό,τι ήταν μπερδεμένο. Είναι ο φθηνότερος τρόπος να ανακαλύψετε ότι ο κωδικός του status page υπάρχει μόνο στο μυαλό ενός πρώην συναδέλφου.
Αν η ομάδα σας είναι πολύ μικρή για να κρατά pager πάνω από τη δουλειά στα features, ή αν τα alerts είναι τόσο θορυβώδη που κανείς δεν τα εμπιστεύεται, αυτή ακριβώς είναι η δουλειά που αναλαμβάνει το managed DevOps μας: καθαρίζουμε το alerting, γράφουμε τα runbooks και μοιραζόμαστε το βάρος του on-call.
Συχνές ερωτήσεις
Τι πρέπει να περιλαμβάνει ένα incident response runbook;
Τουλάχιστον: επίπεδα σοβαρότητας με βάση την επίπτωση στους πελάτες, ρόλους (incident commander, responders, comms lead, scribe), checklist για τα πρώτα 15 λεπτά, πρότυπα για εσωτερικές ενημερώσεις και ενημερώσεις πελατών, διαδρομές κλιμάκωσης με επαφές, κανόνες για rollback και πρότυπο post-incident review. Για ρυθμιζόμενες εταιρείες, προσθέστε βήμα για αποφάσεις αναφοράς GDPR και NIS2.
Πώς στήνουμε on-call σε μικρή ομάδα;
Με εβδομαδιαία rotation και παράδοση μέσα στην εβδομάδα, έναν primary και, από περίπου πέντε engineers, έναν secondary. Εκτός ωραρίου, page μόνο για σοβαρά incidents που βλέπουν οι χρήστες. Αμείψτε το on-call με επίδομα ή ρεπό, αφήστε όποιον ξύπνησε να ξεκινήσει αργότερα, και ελέγχετε κάθε εβδομάδα τα pages για να κόβετε τα άχρηστα alerts.
Πότε ένα alert πρέπει να είναι page και πότε ticket;
Page μόνο για συμπτώματα ορατά στους χρήστες, επείγοντα και με κάτι που μπορεί να γίνει: ανεβασμένο error rate, υψηλό latency, αποτυχημένα synthetic checks σε βασικές ροές. Αιτίες χωρίς επίπτωση στους χρήστες, όπως υψηλό CPU σε ένα node, δίσκος που γεμίζει αργά ή πιστοποιητικό που λήγει σε μια εβδομάδα, πάνε σε ticket ή dashboard.
Τι είναι το blameless postmortem;
Το blameless postmortem, ή post-incident review, εξετάζει τι στο σύστημα και στη διαδικασία επέτρεψε να συμβεί ένα incident, αντί για το ποιος έκανε λάθος. Καταγράφει timeline, επίπτωση, παράγοντες και action items με owners. Χωρίς ενοχοποίηση, οι άνθρωποι μοιράζονται τις λεπτομέρειες που πραγματικά εμποδίζουν το incident να ξανασυμβεί.