case study · serverless · 2026

Cloud Detective — AWS account scanner

A serverless AWS scanner for cost, inventory and security posture. It tracks findings, generates diagrams from discovered resources and uses AI only to explain deterministic results.

problem

One view of AWS cost, inventory and exposure

Cloud accounts drift. Resources outlive the reason they were created, cost appears in places nobody looks, and the only complete picture of what exists is whatever the console will show you one page at a time. I wanted a system that answered three questions on a schedule — what is running, what is it costing, what is exposed — and could then explain any single answer without me going back to the console.

Detection and diagram generation are deterministic, fixture-tested and read-only. The AI layer is optional and disabled by default. It explains findings but does not create them.

architecture

Scheduled scans, finding history and generated diagrams

Daily detectors scan the account and write findings into DynamoDB with a real lifecycle — new, open, resolved — so a finding that comes back is not indistinguishable from one that never left. A plain-text digest goes out by SNS. On top of that sits a Cognito-authenticated dashboard, an LLM chat that investigates the live account through read-only tools, and an on-demand architecture generator that emits draw.io XML and SVG with real AWS icons.

Multi-account scanning fans out over cross-account read-only roles, tracked in an SSM registry that the dashboard writes to when an account is onboarded.

decisions and tradeoffs

Constraints that shaped the design

Provider-agnostic LLM client instead of Bedrock
Bedrock was blocked account-wide, so the AI client was separated from any single provider. Model requests are the only part of the workflow sent outside the AWS account.
Serve the dashboard from the API Lambda
CloudFront was unavailable in this account, so one function serves both the static application and the API. This simplified deployment but coupled content delivery to the application backend. ClearSky replaced it with a CDN.
Diagram generation as code, not as an AI feature
The generator is deterministic: same account state, same diagram. An LLM drawing architecture would be plausible and occasionally wrong, which is the worst possible property for a diagram someone is about to trust.
Create Cognito users with a permanent password
Invite emails were unreliable in practice. Skipping the invite flow removes a dependency on email delivery from the critical path of getting in at all.

what broke

Partial scans resolved findings from the wrong accounts

Partial scans silently resolved other accounts' findings. The reconcile step assumed each run scanned every account, so any unseen finding was marked resolved. Multi-account scans broke that assumption. The fix passes the set of scanned accounts into reconciliation and limits resolution to those accounts.

Bedrock was blocked account-wide — every model, every API. It read like an IAM problem and was not; it was a plan-level restriction, confirmed through a support ticket. That is what forced the provider-agnostic client above.

The first architecture generator drew arrows through its own boxes. An orthogonal corridor router produced overlapping edges as soon as the graph had any depth. It was rewritten into tiered columns with barycenter ordering and per-gap channels, later curved beziers. A separate bug had same-named resources in different services colliding into one diagram node, fixed by keying every node on type:id rather than on its name.

numbers

Scope and outcome

Cloud Detective became the foundation for ClearSky. The successor retained the detector and diagram concepts while replacing the Lambda-served frontend and account-specific AI integration.