An autonomous, multi-agent system that reviews Terraform pull requests against organizational policies, flags violations, auto-generates fixes, and delivers ready-to-merge PRs, so senior DevOps engineers only need to review and approve.
Junior engineers push Terraform changes that violate company policies — public S3 buckets, missing tags, oversized instances in dev, open security groups. Senior engineers spend hours manually reviewing every PR against internal policies. Existing tools like Checkov and OPA catch generic best practices, but can't enforce nuanced, org-specific policies written in natural language ("DR-tagged instances in us-east-1 must not be modified without VP approval").
When a PR is opened, the CI pipeline sends the Terraform plan to TerraGuard. Two AI agents take over:
Agent 1 (Reviewer) — Parses the plan, retrieves company policies and current infrastructure state via RAG, and runs each change through policy checks. Produces a pass/fail verdict per check with reasoning.
Agent 2 (Fixer) — If violations are found, this agent reads the original Terraform code, retrieves the relevant policies, writes corrected HCL, pushes a fix branch, and opens a new PR via GitHub MCP. The CI pipeline validates the fix automatically.
The senior engineer sees a dashboard with green/red check results, agent reasoning, and links to both PRs. They merge whichever is correct. On merge, the current infrastructure state is re-indexed in RAG so the next review has full context.
GitHub PR → CI Pipeline (GitHub Actions)
↓
terraform plan → JSON
↓
FastAPI Webhook Receiver
↓
┌─────────────────────┐
│ Agent 1: Reviewer │ ← RAG (policies + current state)
│ (LangGraph) │
└────────┬────────────┘
↓
┌──────┴──────┐
│ │
All Pass Violations
│ │
↓ ↓
Email Senior ┌──────────────────┐
Engineer ✅ │ Agent 2: Fixer │ ← RAG (policies + current state)
(Gmail MCP) │ (LangGraph) │
└────────┬─────────┘
↓
Push fix branch + Open PR
(GitHub MCP)
↓
CI Pipeline re-validates
↓
Agent 1 re-reviews
↓
Email Senior Engineer
with fix PR link ✅
↓
Senior merges → State re-indexed in RAG
| Layer | Technology |
|---|---|
| Frontend | React, TypeScript, Tailwind CSS |
| Backend | FastAPI, Python |
| Agent Orchestration | LangGraph |
| RAG | ChromaDB / Pgvector, OpenAI Embeddings |
| LLM | Claude / GPT-4 |
| MCP Integrations | GitHub MCP (PRs, branches, file edits), Gmail MCP (notifications) |
| Database | PostgreSQL (PR history, check results, agent decisions) |
| CI/CD | GitHub Actions |
| IaC | Terraform (sample configs for demo) |
| Containerization | Docker, Docker Compose |
Receives parsed Terraform plan. For each resource change:
- Retrieves relevant policies from RAG (e.g., tagging policy for a new EC2 instance)
- Retrieves current infrastructure state from RAG (e.g., does a similar resource already exist?)
- Evaluates the change against each applicable policy
- Produces a structured check result: check name, pass/fail, reasoning, policy referenced
Decision branching (LangGraph):
- All checks pass → notify senior engineer, mark PR as "Approved"
- Any check fails → notify senior engineer of violations, hand off to Agent 2
Receives violation list + original Terraform code:
- For each violation, retrieves the policy and determines the correct fix
- Modifies the Terraform HCL to resolve each violation
- Pushes fix to a new branch via GitHub MCP
- Opens a PR via GitHub MCP with description explaining each fix
Validation loop:
- CI pipeline runs on fix PR →
terraform validate+terraform plan - If validation fails → Agent 2 retries (max 3 attempts)
- If validation passes → plan JSON sent back to Agent 1 for re-review
- If re-review passes → email senior engineer with fix PR link
- Terraform validate — catches syntax errors and provider issues from LLM hallucinations
- Agent 1 re-review — catches policy violations the fix might introduce
- Human approval — senior engineer reviews and merges, agent never has merge permissions
The policies/ directory contains the company's infrastructure policies that agents reference during review. These are self-authored documents simulating a real organization's internal standards:
- tagging_policy.md — Required tags per environment, team ownership rules, cost allocation tags
- instance_types.md — Allowed instance types per environment, GPU usage restrictions, reserved instance rules
- security_groups.md — Ingress/egress rules, prohibited CIDR blocks, port restrictions by environment
- naming_conventions.md — Resource naming patterns:
{env}-{team}-{service}-{resource} - environment_rules.md — Dev/staging/prod restrictions, cross-environment access rules, DR resource protections
- escalation_policy.md — Severity thresholds, who gets notified for what, approval requirements
On PR merge, the current Terraform state is also indexed into the vector store, giving Agent 1 awareness of what's already deployed.
| MCP Server | Used By | Purpose |
|---|---|---|
| GitHub MCP | Agent 2 | Read PR diffs, push fix branches, open fix PRs, create issues |
| Gmail MCP | Both Agents | Notify senior engineer of review results (pass or violations + fix PR) |
MCP is the execution layer — without it, agents produce recommendations. With it, they act.
- Python 3.11+
- Node.js 18+
- PostgreSQL
- Docker & Docker Compose
- GitHub account with a test repository
- OpenAI API key (for embeddings) + Anthropic/OpenAI key (for LLM)
# Clone
git clone https://github.com/dpakks/terraguard.git
cd terraguard
# Environment variables
cp backend/.env.example backend/.env
# Fill in: DATABASE_URL, LLM_API_KEY, GITHUB_TOKEN, GMAIL_MCP_CONFIG
# Start services
docker-compose up -d
# Index policy documents into vector store
python backend/app/rag/vector_store.py --index-policies
# Start backend
cd backend && uvicorn app.main:app --reload
# Start frontend
cd frontend && npm install && npm run dev- Push a Terraform change to your test repo and open a PR
- The CI pipeline sends the plan JSON to your local backend (use ngrok for webhook forwarding)
- Watch the dashboard — checks appear in real-time with green/red results
- If violations found, Agent 2 opens a fix PR automatically
- Merge and verify state re-indexing
Track and document these:
- Precision/Recall — Seed 50 PRs with known violations. How many does Agent 1 catch? How many false positives?
- Fix success rate — What % of Agent 2's fixes pass
terraform validateon first attempt? - Retry rate — How often does Agent 2 need multiple attempts?
- End-to-end latency — Time from webhook received to email sent
- Cost per review — LLM tokens consumed per PR review cycle
- Failure documentation — What policies are too ambiguous for RAG? Where does Agent 2 hallucinate?
MIT