Git, CI/CD & GitOpsCXIII · Observability IntegrationCorrelation
Deploy events and correlation — the timeline view
What you'll learn
- Distinguish a deploy annotation (point in time) from a deploy event (typed structured record)
- Emit a deploy event from the pipeline into the observability backend with commit SHA, build number, and actor
- Correlate a metric spike, a deploy event, and a trace by timestamp and reference
- Recognise the timeline view as the on-call interface that compresses deploys, alerts, and traces into one queryable surface
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
The change-cause annotation from the previous lesson marks the wall-clock moment a deploy reached production. The mark is necessary; the mark is not sufficient. The mark points at a time; the on-call engineer still needs the typed structured record behind the mark - the commit, the build, the actor, the rollout status, the artifact digest. The annotation is the line on the panel; the deploy event is the record the investigator clicks through.
Annotations versus events
A deploy annotation is a single timestamped marker. It serves one purpose: it draws a line on a panel at the moment the deploy happened. The annotation is small by design; it carries a string value that the engineer reads.
A deploy event is a typed structured record. It carries the commit SHA, the build number, the actor, the artifact digest, the deploy job URL, the environment, and any other field the team has decided to record. The event is indexed and queryable; the annotation is not.
flowchart TB
A["Deploy job\nin CI"] -->|"emit event"| B["Event store\nwith structured payload"]
A -->|"annotate"| C["Workload object\nkubernetes.io/change-cause"]
B --> D["Grafana\nEvents panel"]
C --> E["Grafana\nAnnotation line"]
D --> F["Investigator\nclick for full context"]
E --> F
The two surfaces complement each other. The annotation answers “when did this happen?”. The event answers “what exactly happened, and who did it?”. A team that has only the annotation can locate the deploy on the timeline; a team that has only the event can record the change but cannot place it on the panel. The team needs both.
Emitting a deploy event from the pipeline
The pipeline emits a deploy event at the same moment it writes the change-cause annotation. The event is a structured HTTP POST to the observability backend’s annotation or event API:
NAME=api
SHA=7a3f9d2
BUILD=4527
ACTOR=octocat
URL=https://github.com/acme/platform/actions/runs/4527
MESSAGE="bump api to v3.4.1"
kubectl annotate deploy $NAME \
kubernetes.io/change-cause="$MESSAGE" --overwrite
curl -X POST "$GRAFANA_URL/api/annotations" \
-H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d "$(cat <<'JSON'
{
"dashboardId": $DASHBOARD_ID,
"tags": ["deploy", "production", "$NAME"],
"text": "$MESSAGE",
"data": {
"sha": "$SHA",
"build": "$BUILD",
"actor": "$ACTOR",
"url": "$URL"
}
}
JSON
)"
The annotation gives Grafana the line on the panel. The event payload carries the typed fields the on-call engineer clicks through to recover. A team that distinguishes the two surfaces understands that the annotation is a display hint and the event is the investigative record.
Correlating metric, deploy, and trace
Three signals must agree for an investigation to proceed quickly: the metric shows the regression, the deploy event shows what changed, and the trace shows the affected requests. The correlation is by timestamp and by reference.
- Timestamp correlation. A spike at 14:23 on the metric panel with a deploy event at 14:21 is a strong deploy-caused signal. The two timestamps do not have to be identical; the deploy event is the prior in the causal chain.
- Reference correlation. The deploy event carries the commit SHA and the build number. The trace carries the request attributes - service version, deployment label - which the investigator matches to the deploy. The two references are the durable identifier that ties the metric to the change.
The timeline view as the on-call interface
The on-call engineer’s first action during an incident is to open the timeline. The timeline shows the metric panels, the deploy events, the alert markers, and the trace markers in a single scrollable view. The engineer reads the timeline top-to-bottom: what was the last deploy before the spike, what alerts fired, what traces have the affected service version.
The timeline compresses the investigation. A team that has a timeline view answers “what changed” in seconds; a team that has only the metric panel answers the same question by opening five tabs.
Production discipline
- Emit the deploy event from the pipeline at the same step as the annotation. The two records must be atomic; an event without an annotation, or an annotation without an event, is half a record.
- Carry the SHA, the build number, the actor, and the build URL in the event payload. A future investigator will need all four.
- Correlate by reference, not by exact timestamp. Clock skew is real; reference correlation is not.
- Surface the timeline view as the on-call default. The dashboard the engineer opens first must be the timeline; everything else is a drill-down.
- Backfill deploy events for the previous window. A timeline that starts in the middle of last week is a timeline that loses last week’s incidents.
Cross-course references
- Observability course - Part CX (MajorIncidents) covers annotation sources and the HTTP API used to emit the event from the pipeline.
- Observability course - Part LII (Exemplars) covers the metric-to-trace pivot that closes the correlation loop on the trace side.
- This course, Part LXIV (AuditChain) covers the deployment claim and the deployment receipt, which are the durable records that the deploy event complements.
- This course, Part LIX (Rollback) covers the rollback discipline that uses the same correlation to identify which deploy caused a regression.
Quiz
Knowledge check · 4 questions
Q1. What is the operational difference between a deploy annotation and a deploy event?
Q2. Clock skew between the CI runner and the observability backend makes timestamp-based correlation unreliable; reference-based correlation by SHA or build number is unaffected by clock skew.
Q3. List the four fields a deploy event payload should carry for postmortem use, beyond the annotation string.
Q4. Diagnose the correlation failure and recommend the structural fix.
Team T has a Grafana dashboard with deploy annotations. The annotations are written correctly from the pipeline. However, the team has no deploy event stream: there is no structured record of the SHA, the build number, or the actor. Six weeks after a regression, the team is asked to reconstruct which commit caused the regression. The annotation text says 'bump api to v3.4.1', which is not enough to identify the commit. The engineer opens GitHub Actions, finds the run that matches the timestamp, and reads the commit by hand. The reconstruction takes 45 minutes.
Passing score: 75%. Answers are checked in this browser.