9 views
This guide covers AI incident ChatOps with production-focused examples and trade-offs.
ChatOps AIs that “just fix prod” are how you get a second outage. The useful product is the opposite: from a Slack alert, draft a change ticket and runbook steps grounded in CloudWatch/X-Ray citations—then wait for a human to approve any mutating tool.⚡ TL;DR: Subscribe to alert events; gather metrics/logs with read-only IAM; draft ticket + dry-run commands; require explicit emoji/button approval before any write. Log the full agent transcript. Pair with AI On-Call Copilots and LLM Incident Runbooks.
Threat model: what auto-remediation actually breaks — AI incident ChatOps
Auto-remediators look clever in demos and catastrophic under partial failure:- Restarting pods that were failing closed on a bad config → flap loop
- Scaling write capacity because of a thundering herd that needed shed load, not more RCU
- Rolling back a deploy that fixed a different symptom while the real bug was a dependency outage
Read-only gathering
typescript
✅ Citations mandatory; mutate flag false by default.// chatops/draft.ts
export async function draftFromAlarm(alarm: CloudWatchAlarmEvent) {
const signals = await Promise.all([
logsInsights(alarm.metricQuery),
xrayTraceSummaries(alarm.service),
recentDeploys(alarm.service),
]);
const draft = await bedrock.converse({
system: "Propose remediation; NEVER claim you executed anything. Cite signal IDs.",
messages: [{ role: "user", content: JSON.stringify({ alarm, signals }) }],
});
return {
ticket: {
title: `[sev] ${alarm.alarmName}`,
body: draft.markdown,
citations: signals.citationIds,
},
proposedCommands: draft.commands.map(asDryRun),
mutate: false,
};
}
function asDryRun(cmd: string) {
if (/\b(apply|delete|rm|put-item|update-function-code)\b/i.test(cmd)) {
return `# DRY-RUN ONLY\n# ${cmd}`;
}
return cmd;
}
❌ Agent with
kubectl delete pod bound to a Slack mention.
IAM split: gather vs elevate
| Role | Permissions | Lifetime |
|---|---|---|
chatops-reader |
CloudWatch, Logs Insights, X-Ray, ECS Describe, CodeDeploy Get | Always on |
chatops-elevated |
Scoped mutate actions for one service | Minted 15 min after dual approval |
chatops-deny-breakglass |
Explicit Deny on IAM/Org/KMS key delete | Never assumable by bot |
json
Mint elevation only after Slack approval; put the approver user ID and ticket ID into the STS session tags for forensics.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "ReaderOnly",
"Effect": "Allow",
"Action": [
"cloudwatch:GetMetricData",
"logs:StartQuery",
"logs:GetQueryResults",
"xray:GetTraceSummaries",
"ecs:Describe*"
],
"Resource": "*"
}]
}
Approval UX
typescript
Human-in-the-loop patterns: keep approvals explicit as in AI On-Call Copilots. Grounding in Live Tail: LLM Incident Runbooks.
// Slack interactive button
export async function onApprove(action: SlackAction) {
assertOnCall(action.user);
assertChangeTicketOpen(action.ticketId);
// Dual control for prod-touching tools
await requestSecondApprover(action);
await enqueueMutatingTool(action.commandId); // still audited
}
What the ticket must contain
markdown
Reject drafts that lack citations or invent metric names. A verifier step can re-run the Logs Insights query ID and fail the draft if the query 404s.
## Proposed change
- Service: checkout-api
- Hypothesis: elevated DynamoDB throttles after deploy abc123
- Evidence: Logs Insights query Q-441, X-Ray trace 1-...
- Steps (dry-run):
1. aws dynamodb describe-table ...
2. # scale write capacity (APPROVAL REQUIRED)
- Rollback: redeploy previous alias weight 100%
- Blast radius: checkout write path only; reads unaffected
Transcript retention and postmortems
Store every agent turn (prompt, tool args, tool results, Slack actions) unders3://incidents/{ticketId}/chatops/. Redact secrets with a allowlist of field names. Link the transcript from the postmortem template so “what did the bot suggest?” is one click — see Deterministic Replay.
Game-day drill script
- Inject a synthetic alarm with known-good evidence
- Confirm bot posts a draft ticket within 2 minutes
- Attempt to trigger mutate without approval — must fail closed
- Approve with on-call + second approver; confirm elevate role mint
- Verify transcript lands and elevated session expires ≤15 minutes
Alert ingress without write paths
Subscribe the drafter to EventBridge/CloudWatch alarm notifications (or a SQS buffer), never to a webhook that can invoke shell. Parse the alarm ARN, map to owning service via a CMDB tag, and refuse to draft if the service lacks a runbook pointer. This keeps unknown alarms from becoming hallucinated remediations.typescript
Prefer a 30–60s debounce so flapping alarms do not spawn duplicate tickets. Deduplicate on export async function ingress(evt: AlarmEvent) {
const svc = await cmdb.lookup(evt.alarmArn);
if (!svc?.runbookUrl) {
await slack.post({ text: `No runbook for ${evt.alarmName}; human triage required.` });
return;
}
return draftFromAlarm(evt);
}
alarmArn + stateTransitionTime window.
Closing checklist
- [ ] ChatOps IAM is read-only until approval mints a short-lived elevate role
- [ ] Every draft cites metrics/logs/deploy IDs
- [ ] Slack buttons record user + timestamp + ticket ID
- [ ] Mutating tools dual-controlled; transcript retained
- [ ] No auto-remediation webhooks from alert → shell
- [ ] Sev-1 runbooks tested in game days with the bot in draft-only mode
- [ ] Dry-run prefixer strips apply/delete verbs before posting
- [ ] STS session tags carry tenant/service/approver for audit
Related reading
- AI On-Call Copilots: Suggest Runbooks Without Mutating Production
- LLM Incident Runbooks: Ground On-Call Answers in CloudWatch Signals
- Deterministic Replay: Agent Sessions You Can Debug in Postmortems
- Secure AI Sandboxes: Ephemeral ECS Tasks for Agent Tool Execution
Related: Evaluating AI Coding Tools: Blind A/B Tests on Real Tickets · AI Pair Programming Metrics: Cycle Time Without Vanity Accept Scores · CodeBuild Spec Sandboxes for AI Coding Agents: Ephemeral Builds Without ECS Sprawl
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.

Pingback: CloudWatch Logs Anomaly Detection: Ignore Deploy Noise, Catch Novel Errors - CheatCoders