Build an AI Terraform Cost Estimator Using Claude (2026)
Before you run terraform apply, wouldn't you want to know how much it'll cost? Build an AI cost estimator that reads your Terraform plan output and gives you a detailed cost breakdown using Claude as the reasoning engine.
You're about to run terraform apply on a new EKS cluster setup. Do you know what it'll cost?
Infracost exists but requires setup and API registration. What if you could just pipe your terraform plan output to an AI and get a cost breakdown in seconds?
In this post we'll build exactly that — an AI Terraform cost estimator that:
- Reads
terraform plan -jsonoutput - Extracts all resources being created/modified
- Uses Claude to identify cost-bearing resources and estimate costs
- Outputs a formatted cost report
Architecture
terraform plan -json → cost-estimator.py → Claude API → Cost Report
Simple, no external APIs needed except Claude/OpenAI.
Prerequisites
- Python 3.11+
- Anthropic API key
- Terraform project to test with
Step 1: The Core Estimator
#!/usr/bin/env python3
# cost_estimator.py
import anthropic
import json
import sys
import subprocess
from pathlib import Path
def get_terraform_plan(terraform_dir: str = ".") -> dict:
"""Run terraform plan and capture JSON output."""
print("Running terraform plan...")
# Generate plan file
result = subprocess.run(
["terraform", "plan", "-out=tfplan.binary"],
cwd=terraform_dir,
capture_output=True,
text=True
)
if result.returncode != 0:
print(f"terraform plan failed:\n{result.stderr}")
sys.exit(1)
# Convert plan to JSON
result = subprocess.run(
["terraform", "show", "-json", "tfplan.binary"],
cwd=terraform_dir,
capture_output=True,
text=True
)
return json.loads(result.stdout)
def extract_resource_changes(plan: dict) -> list[dict]:
"""Extract resources being created or modified from the plan."""
changes = []
resource_changes = plan.get("resource_changes", [])
for change in resource_changes:
actions = change.get("change", {}).get("actions", [])
# Only care about create, update, replace
if not any(a in actions for a in ["create", "update", "replace"]):
continue
resource_type = change.get("type", "")
resource_name = change.get("name", "")
after_config = change.get("change", {}).get("after", {})
changes.append({
"type": resource_type,
"name": resource_name,
"action": actions[0] if actions else "unknown",
"config": after_config
})
return changes
def estimate_costs_with_ai(resources: list[dict], region: str = "us-east-1") -> str:
"""Use Claude to estimate costs for the resources."""
client = anthropic.Anthropic()
# Build the resource summary for the prompt
resource_summary = json.dumps(resources, indent=2)
prompt = f"""You are an AWS cost estimation expert. I'm about to create/modify the following Terraform resources in region {region}.
RESOURCES:
{resource_summary}
Please provide:
1. **COST SUMMARY TABLE** — For each resource that has a cost, provide:
| Resource | Type | Config | Monthly Cost (USD) |
2. **TOTAL MONTHLY ESTIMATE** — Sum of all costs
3. **TOTAL ANNUAL ESTIMATE** — Monthly × 12
4. **COST BREAKDOWN BY CATEGORY:**
- Compute
- Storage
- Network
- Database
- Other
5. **COST OPTIMIZATION TIPS** — 2-3 specific suggestions to reduce cost based on the resources being created
6. **ASSUMPTIONS** — Any assumptions you made (e.g., "assumed 730 hours/month for EC2")
Important notes:
- Use current 2026 AWS pricing (on-demand)
- If you're unsure of exact pricing, provide a range
- Mark free-tier-eligible resources with [FREE TIER]
- For resources with no cost (IAM roles, security groups, etc.), you can skip them or note "No direct cost"
- Format numbers clearly (e.g., $12.50/month, not $12.5)
Be specific and practical — this will be used to evaluate whether to proceed with this infrastructure change."""
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2000,
messages=[
{"role": "user", "content": prompt}
]
)
return message.content[0].text
def load_plan_from_file(filepath: str) -> dict:
"""Load a pre-generated terraform plan JSON file."""
with open(filepath) as f:
return json.load(f)
def main():
import argparse
parser = argparse.ArgumentParser(description="AI-powered Terraform cost estimator")
parser.add_argument("--plan-file", help="Path to terraform plan JSON file")
parser.add_argument("--dir", default=".", help="Terraform directory (runs terraform plan)")
parser.add_argument("--region", default="us-east-1", help="AWS region for pricing")
parser.add_argument("--output", help="Save report to file")
args = parser.parse_args()
# Get plan
if args.plan_file:
print(f"Loading plan from {args.plan_file}...")
plan = load_plan_from_file(args.plan_file)
else:
plan = get_terraform_plan(args.dir)
# Extract resources
resources = extract_resource_changes(plan)
if not resources:
print("No resource changes found in plan.")
sys.exit(0)
print(f"\nFound {len(resources)} resource change(s):")
for r in resources:
action_symbol = {"create": "+", "update": "~", "replace": "±", "delete": "-"}.get(r["action"], "?")
print(f" {action_symbol} {r['type']}.{r['name']}")
print("\nEstimating costs with AI...")
# Get cost estimate
report = estimate_costs_with_ai(resources, region=args.region)
# Print report
print("\n" + "="*60)
print("TERRAFORM COST ESTIMATE REPORT")
print("="*60)
print(report)
print("="*60)
# Save to file if requested
if args.output:
output_path = Path(args.output)
output_path.write_text(report)
print(f"\nReport saved to {args.output}")
if __name__ == "__main__":
main()Step 2: Try It
pip install anthropic
# Option 1: Point at a Terraform directory (runs plan automatically)
python cost_estimator.py --dir ./my-terraform-project --region us-east-1
# Option 2: Use a pre-generated plan file
terraform plan -out=plan.binary
terraform show -json plan.binary > plan.json
python cost_estimator.py --plan-file plan.json --region eu-west-1
# Save report to file
python cost_estimator.py --dir . --output cost-report.mdExample Output
Given a plan that creates an EKS cluster, RDS instance, and EC2 bastion:
============================================================
TERRAFORM COST ESTIMATE REPORT
============================================================
## COST SUMMARY TABLE
| Resource | Type | Config | Monthly Cost (USD) |
|---|---|---|---|
| eks_cluster | aws_eks_cluster | v1.31, 3 nodes | $73.00 |
| eks_workers | aws_eks_node_group | 3x t3.medium | $100.80 |
| rds_postgres | aws_db_instance | db.t3.medium, 100GB | $85.20 |
| bastion | aws_instance | t3.micro | $8.32 |
| nat_gateway | aws_nat_gateway | 1 AZ | $32.40 |
| ebs_volumes | aws_ebs_volume | 3x 20GB gp3 | $7.20 |
## TOTAL MONTHLY ESTIMATE: $307.32/month
## TOTAL ANNUAL ESTIMATE: $3,687.84/year
## COST BREAKDOWN BY CATEGORY:
- Compute: $182.12 (59%)
- Database: $85.20 (28%)
- Network: $32.40 (11%)
- Storage: $7.20 (2%)
## COST OPTIMIZATION TIPS:
1. **Use Spot instances for worker nodes:** Switching from on-demand t3.medium
to Spot could save 60–70% on EC2 costs (~$60-70/month savings).
Use Karpenter with spot instance support.
2. **Single NAT Gateway:** You're creating 1 NAT Gateway (good).
If deploying in multiple AZs later, consider sharing one NAT Gateway
across AZs in non-prod to save $32/month per additional gateway.
3. **RDS Reserved Instance:** If this is production, a 1-year Reserved Instance
for db.t3.medium saves ~40% vs on-demand ($85 → $51/month = $408/year savings).
## ASSUMPTIONS:
- 730 hours/month for all compute
- EKS cluster pricing at $0.10/hour
- NAT Gateway at $0.045/hour + $0.045/GB data processed (estimated 10GB)
- RDS Multi-AZ not enabled (single AZ pricing)
Step 3: Add It to Your CI Pipeline
# .github/workflows/cost-estimate.yml
name: Terraform Cost Estimate
on:
pull_request:
paths:
- '**.tf'
- '**.tfvars'
jobs:
cost-estimate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.0"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install anthropic
- name: Terraform Init
run: terraform init
working-directory: ./terraform
- name: Generate Terraform Plan JSON
run: |
terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > plan.json
working-directory: ./terraform
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Run Cost Estimator
id: cost
run: |
python cost_estimator.py --plan-file terraform/plan.json --output cost-report.md
echo "report<<EOF" >> $GITHUB_OUTPUT
cat cost-report.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 💰 Terraform Cost Estimate\n\n\`\`\`\n${{ steps.cost.outputs.report }}\n\`\`\``
})Now every Terraform PR automatically gets a cost estimate comment. Engineers see the cost impact before merging infrastructure changes.
Enhancements to Try
1. Compare costs between revisions:
# Compare plan costs vs current state
def compare_costs(old_resources, new_resources):
# Find added/removed resources
added = [r for r in new_resources if r['name'] not in [o['name'] for o in old_resources]]
removed = [r for r in old_resources if r['name'] not in [n['name'] for n in new_resources]]
# Ask Claude for delta cost2. Add actual AWS pricing API:
Use boto3 to fetch real-time pricing data and give Claude accurate numbers instead of relying on its training data.
3. Multi-cloud support: The same pattern works for GCP and Azure Terraform resources — just adjust the prompt to reference GCP/Azure pricing.
4. Slack notification:
Post the cost estimate to a #terraform-costs Slack channel for team visibility.
Affiliate note: Anthropic Claude API — the intelligence behind this estimator. Start free with $5 of credit. For cost optimization at scale, Infracost provides a dedicated solution with 1,000+ resource types supported — worth considering if you need production-grade accuracy.
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
How to Use AI Agents to Automate Terraform Infrastructure Changes in 2026
AI agents can now plan, review, and apply Terraform changes from natural language. Here's how agentic AI is transforming infrastructure-as-code workflows.
AI-Driven Capacity Planning for Kubernetes Clusters (2026)
How to use AI and machine learning for Kubernetes capacity planning. Covers predictive autoscaling, cost optimization, tools like StormForge and Kubecost, and building custom ML models for resource forecasting.
Build an AI-Powered Terraform Drift Detection System
Terraform drift happens silently. Here's how to build an automated drift detector using Terraform plan + Claude API that alerts your team and explains exactly what changed.