🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Build an AI Terraform Cost Preview Bot with Claude API

Terraform plan output tells you what will change, not what it'll cost. Build a bot that comments the estimated monthly cost delta directly on every infrastructure PR, with Claude API explaining which specific resources drive the change.

Shubham4 min read
Share:Tweet

Cost surprises from infrastructure changes are almost always visible in the terraform plan output — a new db.r6g.2xlarge instead of db.r6g.large, a NAT gateway added per AZ instead of one shared — but nobody reads plan output looking for cost implications during a normal PR review. This bot surfaces the cost delta explicitly, with plain-English explanation of what's driving it.

Setup

bash
pip install anthropic infracost-python    # or shell out to the infracost CLI directly

Cost Estimation via Infracost

python
import subprocess
import json
import anthropic
 
client = anthropic.Anthropic()
 
 
def get_cost_estimate(terraform_dir: str) -> dict:
    """Infracost does the actual pricing math — this tool's value is
    explaining the WHY, not recalculating cloud pricing itself."""
    result = subprocess.run(
        ["infracost", "breakdown", "--path", terraform_dir, "--format", "json"],
        capture_output=True, text=True
    )
    return json.loads(result.stdout)
 
 
def get_cost_diff(terraform_dir: str, base_branch: str) -> dict:
    result = subprocess.run(
        ["infracost", "diff", "--path", terraform_dir, "--compare-to", f"infracost-base-{base_branch}.json"],
        capture_output=True, text=True
    )
    return json.loads(result.stdout)

Explanation Generation With Claude

python
EXPLAIN_PROMPT = """Explain this Terraform infrastructure cost change in
plain English for a PR review comment.
 
Cost diff data:
{cost_diff}
 
Terraform plan resource changes:
{plan_summary}
 
Write a concise explanation that:
1. States the total monthly cost delta clearly upfront
2. Identifies the SPECIFIC resource(s) driving the biggest cost change
   and why (e.g. "instance type upgraded from r6g.large to r6g.2xlarge"
   not just "compute costs increased")
3. Flags if any single change looks like it might be unintentional
   (e.g. a resource count went from 1 to 3 across all AZs when the PR
   description suggests only one new environment was intended)
4. Keep it under 150 words — this goes in a PR comment, not a report
 
Do not just restate numbers — explain what's actually driving them."""
 
 
def generate_cost_explanation(cost_diff: dict, plan_summary: dict) -> str:
    response = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": EXPLAIN_PROMPT.format(cost_diff=cost_diff, plan_summary=plan_summary)
        }]
    )
    return response.content[0].text

GitHub Actions Integration

yaml
name: Terraform Cost Preview
on:
  pull_request:
    paths: ["**.tf"]
 
jobs:
  cost-preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - uses: infracost/actions/setup@v3
        with:
          api-key: ${{ secrets.INFRACOST_API_KEY }}
 
      - name: Generate baseline cost
        run: |
          git checkout ${{ github.event.pull_request.base.sha }}
          infracost breakdown --path . --format json --out-file infracost-base.json
 
      - name: Generate cost diff
        run: |
          git checkout ${{ github.event.pull_request.head.sha }}
          infracost diff --path . --compare-to infracost-base.json --format json --out-file cost-diff.json
 
      - name: Generate AI explanation and post comment
        run: python cost_bot.py --diff cost-diff.json --pr ${{ github.event.pull_request.number }}
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Example PR Comment

markdown
## 💰 Infrastructure Cost Preview
 
**Estimated monthly cost change: +$847/month** (current: $2,140 → new: $2,987)
 
The increase is driven almost entirely by one change: the `payments-db`
RDS instance is being upgraded from `db.r6g.large` to `db.r6g.2xlarge`
(+$612/mo), plus a new read replica being added in `us-west-2` (+$235/mo).
 
⚠️ Worth double-checking: the PR description mentions "prep for Black
Friday traffic" but this instance upgrade is permanent, not autoscaled —
if this is meant to be temporary capacity for a traffic event, consider
using RDS's built-in storage autoscaling or a scheduled instance resize
instead of a permanent 2x instance class bump.
 
All other resource changes in this PR are cost-neutral or under $10/mo.

Why the "Worth Double-Checking" Flag Matters Most

The raw cost number is useful but the highest-value output is catching intent mismatches — a PR description saying "temporary capacity for an event" paired with a permanent infrastructure change is exactly the kind of thing a fast PR review misses, because reviewers are checking correctness of the Terraform, not cross-referencing the PR description against the actual cost model. This is a place where Claude reasoning across both the cost diff and the PR's stated intent catches something a raw infracost diff number alone never would.


More AI FinOps tooling? Read our FinOps guide for DevOps engineers and Build AI cost anomaly detector with Claude API.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

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

Comments