The Problem: Cloud Cost Surprises After Deployment
Six months ago, our team shipped a routine Terraform update to boost staging database throughput. Automated tests, linting, and security scans all passed without issue. Three weeks later, finance flagged an unexpected $4,200 spike in our AWS invoice. An engineer had inadvertently provisioned multi-AZ provisioned IOPS SSD (io2) storage with 10,000 IOPS across three non-production clusters instead of standard gp3 volumes.
Most FinOps workflows rely on retrospective dashboards like AWS Cost Explorer or CloudHealth. While helpful for monthly accounting, they alert you only after the money is already spent. Triaging runaway infrastructure expenses after running terraform apply creates avoidable friction between platform teams and developers.
Shift-left practices transformed automated testing and vulnerability scanning. Bringing that same proactive mindset to cloud spending stops costly provisioning mistakes before code ever reaches your main branch.
Core Concepts: How Infracost Shifts Cost Awareness Left
Infracost parses Terraform HCL code or JSON execution plans and maps every declared resource against vendor pricing data across AWS, Azure, and Google Cloud. Because it estimates costs statically, you get rapid pricing insights without querying live cloud infrastructure.
Key Architectural Components
- Cloud Pricing API: A managed service tracking over 3 million cloud SKUs that continuously updates whenever providers alter their hourly or tier-based rates.
- Diff Engine: Calculates the monthly cost delta between your target branch and the incoming pull request, breaking down additions, updates, and removals.
- Usage Profiles: Allows teams to specify dynamic usage parameters—such as 500 GB of standard S3 storage or 25 million Lambda requests—via an
infracost-usage.ymlfile. - CI/CD Commenter: Publishes a markdown breakdown directly into GitHub Pull Requests or GitLab Merge Requests.
Hands-On Practice: Integrating Infracost into GitHub Actions
Let’s install the CLI locally, inspect a sample resource diff, and configure an automated GitHub Actions workflow.
Step 1: Install and Authenticate the Infracost CLI
First, install the CLI binary on your workstation to inspect cost breakdowns during local development:
# macOS installation via Homebrew
brew install infracost
# Linux installation
curl -fsSL https://raw.githubusercontent.com/infracost/infracost/master/scripts/install.sh | sh
# Authenticate to retrieve your API key
infracost auth login
Step 2: Generate a Local Cost Breakdown
Consider a simple Terraform configuration defining an EC2 instance with an attached EBS root disk:
# main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web_app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "m5.xlarge"
root_block_device {
volume_size = 100
volume_type = "gp3"
}
}
Run the cost calculation directly against your directory:
infracost breakdown --path .
Infracost parses the HCL files and prints a monthly summary:
Name Monthly Qty Unit Monthly Cost
aws_instance.web_app
├─ Instance usage (Linux/UNIX, on-demand, m5.xlarge) 730 hours $140.16
└─ root_block_device
└─ Storage (general purpose SSD, gp3) 100 GB $8.00
OVERALL TOTAL $148.16
Step 3: Automate Pull Request Cost Diffs in GitHub Actions
Catching financial regressions during code review ensures spending stays transparent across engineering teams. Add your API token as a repository secret named INFRACOST_API_KEY, then add this workflow file at .github/workflows/infracost.yml:
name: Infracost Cost Estimation
on:
pull_request:
branches: [ main, master ]
paths:
- 'terraform/**'
- '**.tf'
jobs:
infracost:
name: Infracost PR Cost Diff
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout Base Branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
- name: Setup Infracost
uses: infracost/actions/setup@v3
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
# Generate baseline cost from base branch
- name: Generate Infracost Baseline
run: |
infracost breakdown --path=terraform \
--format=json \
--out-file=/tmp/infracost-base.json
- name: Checkout Current PR Branch
uses: actions/checkout@v4
# Generate diff against baseline
- name: Generate Infracost Diff
run: |
infracost diff --path=terraform \
--format=json \
--compare-to=/tmp/infracost-base.json \
--out-file=/tmp/infracost-diff.json
# Post cost breakdown as a GitHub PR comment
- name: Post Infracost Comment
run: |
infracost comment github --path=/tmp/infracost-diff.json \
--repo=$GITHUB_REPOSITORY \
--github-token=${{ secrets.GITHUB_TOKEN }} \
--pull-request=${{ github.event.pull_request.number }} \
--behavior=update
Step 4: Establish FinOps Guardrails
Visibility is great, but enforcement prevents large accidental commits. You can parse the generated JSON diff with jq and break the build if a pull request increases monthly spend beyond a set limit (e.g., more than $200/month without managerial approval):
# Extract the monthly cost difference using jq
DIFF=$(jq -r '(.diffTotalMonthlyCost // 0)' /tmp/infracost-diff.json)
THRESHOLD=200
echo "Projected monthly change: $$DIFF"
if (( $(echo "$DIFF > $THRESHOLD" | bc -l) )); then
echo "ERROR: Cost increase of $$DIFF exceeds the $$THRESHOLD limit. FinOps approval required."
exit 1
fi
Six Months in Production: Lessons Learned
Running Infracost across 40+ microservices surfaced several practical takeaways for platform engineers:
- Define usage profiles early: Serverless components (AWS Lambda, DynamoDB on-demand, S3 Glacier) default to $0.00 until you supply estimated invocation and storage metrics in
infracost-usage.yml. - Centralize monorepo configs: If your repository maintains distinct environment paths (such as
environments/stagingandenvironments/prod), declare aninfracost.ymlmulti-project config to evaluate all targets concurrently. - Feedback accelerates self-correction: When engineers see a $280/month increase from bumping a compute tier from
c5.2xlargetoc5.4xlargeinside their PR, they often right-size the workload before requesting review.
Summary
Bringing cost visibility directly into GitHub pull requests changes FinOps from a reactive monthly audit into an automated engineering safeguard. Pair Infracost with your existing CI/CD pipelines to keep cloud budgets transparent, manageable, and predictable.

