Architecture
A serverless backend on AWS, built with Terraform. The page in your browser never reads alert payloads itself: it sends them to the backend, and the backend sends back only the state change to draw. Blue boxes are code I wrote; purple boxes are AWS managed services. The numbers follow one signal from start to finish; the steps are explained right below the diagram.
The signal path
What happens when you press a signal
- The payload is sent in its real format. The page (or your curl) posts the example exactly as the real tool would send it — an Alertmanager webhook, a CloudWatch alarm state-change event, or a Kubernetes HPA event — to
POST https://api.hyunsookimdevops.fyi/signal/<your session>. - API Gateway calls the signal Lambda. An HTTP API with a throttle on the whole API in front of a single function.
- The session and rate limit are checked in DynamoDB. Unknown or expired sessions are refused. Each session can send up to 5 signals per second, counted with a conditional update.
- The adapter turns the payload into one state change. It reads only the fields it needs (for example
labels.alertname,detail.state.value,reason) and produces{ signal: "channel-1-down", on: true }. Anything it does not recognise is rejected, and you see a “Rejected” card. - The result is pushed through API Gateway WebSocket to your tab only. The session knows which connection is yours, so a curl from your terminal changes your screen and nobody else's.
- The 3D scene reacts. The page applies the state and shows a card with the source, the alert name and the round-trip time.
What each part does
Your browser
Loads the static site and draws the 3D scene with Three.js. Each tab opens one WebSocket session and only draws the state it receives.
CloudFront + S3
Serves the site over HTTPS from a private bucket that only CloudFront can read (Origin Access Control). DNS is on Cloudflare; the certificate is in ACM.
API Gateway · HTTP
The public entry point at api.hyunsookimdevops.fyi, for signals. CORS is limited to this site, and the API is throttled.
Lambda · signal
The adapter. Reads Alertmanager, CloudWatch and Kubernetes payloads, turns each into one state change, and pushes it to the right browser.
DynamoDB
One small table: which WebSocket connection owns each session, a per-second request counter, and a TTL so old sessions delete themselves.
WebSocket + Lambda · ws
Keeps a live connection to each tab. Creates the session, answers keep-alive pings, and cleans up when the tab closes, so the backend can push to one browser.
Design choices
Serverless, pay per request
Nothing runs while nobody visits. A thousand visitors sending thirty signals each costs well under a dollar, and the account has a hard monthly spend limit.
The browser only draws
The browser is treated as untrusted. It holds no secrets — no tokens, no keys — and only draws { signal, on }. Reading Alertmanager, CloudWatch and Kubernetes formats happens in the Lambda, behind the trust boundary, so copying the front-end code gives you a picture, not the integration. The server answers per session, and CORS allows only this site.
One session per tab, little data kept
Sessions expire after two hours with DynamoDB TTL. No IP addresses are stored, and logs are kept for seven days.
Everything in Terraform
Modules for the static site, the API and the realtime path. Remote state in S3 with a lock file. Each Lambda has its own least-privilege role. Local credentials are short-lived (aws login), with no long-term access keys.
A real constraint I hit
This AWS account was created with the new sign-up experience, which applies AWS-managed SCPs: us-east-1 allows only global services. The first state-bucket apply was denied, so regional resources moved to us-east-2, and only the CloudFront certificate stays in us-east-1.
Not connected yet
- Not connectedReal Prometheus Alertmanager, CloudWatch and Kubernetes. The examples use their real payload formats; connecting them means pointing an Alertmanager
webhook_configsreceiver, an EventBridge API destination, and an event exporter at this endpoint. - Manual for nowDeploys run by hand (
terraform applyand a deploy script). CI/CD is planned.