A multi-agent CLI that reviews your AWS Terraform plan or CloudFormation template against the 6 pillars of the AWS Well-Architected Framework — Security, Reliability, Performance Efficiency, Cost Optimization, Operational Excellence, and Sustainability.
Six specialist agents (one per pillar) independently review your infrastructure, a reconciler agent surfaces the cases where two pillars' recommendations conflict (e.g. Security wants Multi-AZ, Cost flags the doubled spend), and the results are written to a self-contained local HTML report — opened in your browser automatically — with a short summary in the terminal.
$ pillars review ./infra
__ _____ _____ _ _ _____ _____
/ / | __ \_ _| | | | /\ | __ \ / ____|
/ /_ | |__) || | | | | | / \ | |__) | (___
| '_ \ | ___/ | | | | | | / /\ \ | _ / \___ \
| (_) | | | _| |_| |____| |____ / ____ \| | \ \ ____) |
\___/ |_| |_____|______|______/_/ \_\_| \_\_____/
AWS Well-Architected review, six agents at a time
Synthesizing... (terraform plan)
✓ 14 resource change(s)
🔒 Security agent: found 2 issues — 1 blocking.
🛡️ Reliability agent: found 1 finding worth a look.
⚡ Performance Efficiency agent: looks clean, no findings.
💰 Cost Optimization agent: looks clean, no findings.
🛠️ Operational Excellence agent: looks clean, no findings.
🌱 Sustainability agent: looks clean, no findings.
🧭 Reconciler agent: no cross-pillar conflicts, all clear.
Pillar review
⚠ Security 2 findings (1 blocking)
⚠ Reliability 1 finding
✓ Cost Optimization
✓ Performance Efficiency
✓ Operational Excellence
✓ Sustainability
1 blocking · 1 your call · 0 other — see pillars-report.html
pillars-report.html opens automatically (skip with --no-browser) with the full triaged
detail — an AWS-icon architecture diagram at the top (generated from the same resources and
references the pillar agents reviewed), then BLOCKING and YOUR CALL sections expanded, and the
long tail of lower-priority findings collapsed behind a Show N more toggle so it doesn't
dominate the page.
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"The architecture diagram needs Graphviz installed (brew install graphviz on macOS) — optional; if it's not found, the diagram section is skipped and everything
else still works.
Set your Anthropic API key (get one at console.anthropic.com):
cp .env.example .env
# edit .env and add ANTHROPIC_API_KEY=sk-ant-...pillars review figures out what you're pointing it at:
Terraform — a directory runs a live terraform plan (requires terraform and AWS
credentials configured):
pillars review ./path/to/your/terraformOr skip Terraform/AWS entirely with a pre-generated plan file — handy for trying it out:
pillars review ./examples/demo-infra --plan-json ./examples/demo-infra/plan.jsonSecurity note: Terraform values are sanitized before LLM review. The Terraform path uses
Terraform sensitivity metadata plus conservative key-name heuristics to replace sensitive values
with [REDACTED] before building the resource payload sent to the agents. Non-sensitive
Terraform resource data is still sent to the configured LLM provider. This first Terraform
redaction change does not sanitize CloudFormation input or notes loaded from .pillars/context.md.
CloudFormation — point it at a template file directly (.yaml/.yml/.json), no AWS
credentials needed. This reviews what the template defines, not a live diff:
pillars review ./examples/demo-infra-cfn/template.yamlBoth bundled examples plant the same category of flaws (public S3 bucket, hardcoded DB password, single-AZ database with no backups) so you can see the tool actually catch things, in either format.
Static review has an inherent blind spot: a "public" S3 bucket might be a genuine misconfiguration, or it might be the intentional origin of a CloudFront distribution. Two things help the agents tell the difference:
- Resource references are extracted automatically — no action needed. Both the Terraform and
CloudFormation paths detect which resources point at which others (a CloudFront distribution's
Originpointing at an S3 bucket, a security group rule referencing another security group, etc.) and pass that graph to every agent, so they can weigh a resource in context instead of in isolation. - For anything that can't be inferred from the plan/template at all — a fact like "a separate
legacy app writes to this bucket directly, not just through this stack" — write it down in
.pillars/context.mdin the directory you runpillars reviewfrom. It's picked up automatically every run (or point at a different file with--context path/to/notes.md). The CLI prints✓ Using context from ...when something was loaded, so it's never silently ignored.
mkdir -p .pillars
echo "DataBucket is written to directly by a legacy ETL job outside this stack." > .pillars/context.md
pillars review ./examples/demo-infra-cfn/template.yamlAgents weigh this context genuinely rather than treating it as an automatic override — it can justify a design choice, but it won't excuse a real problem the note doesn't actually address.
- The input is normalized into a common resource list — either from
terraform plan+terraform show -json(terraform.py), or by parsing a CloudFormation template'sResourcessection directly (cloudformation.py). Either path produces the sameResourceChangeshape the rest of the pipeline works with, including the cross-resourcereferencesextracted from Terraform's configuration block or CloudFormation'sRef/GetAtt/Subintrinsics. - Six pillar agents review the same resource list in parallel, each scoped to its own rubric (agents/rubrics/), and return structured findings.
- A reconciler agent looks across all six findings sets for the same resource and flags genuine cross-pillar conflicts, resolving the clear-cut ones and leaving true tradeoffs as "your call."
- Independently of the findings — it only needs the resource list (types + references), not the
review results — the same data is rendered into an AWS-icon architecture diagram via
Graphviz and the
diagramslibrary (diagram.py). - The CLI writes a triaged HTML report (render_html.py) with the diagram embedded, opens it in your browser, and prints a short summary to the terminal (render.py).
Built on the Anthropic Python SDK using
claude-sonnet-5 with native structured outputs — no framework, just parallel API calls plus a
reconciliation pass.
Reviews a Terraform plan or a CloudFormation template end-to-end. Not yet built: CDK support,
a live CloudFormation change-set diff (current CFN support reviews the template as-written, not
a diff against a deployed stack), resource-type routing (to skip irrelevant pillars on small
diffs), a .pillars.yml priority config, and interactive follow-up (pillars chat).
pytest