The Price of Speed
Infrastructure as Code (IaC) tools like Terraform and OpenTofu have changed the game, allowing us to deploy global-scale environments with a few lines of HCL. But that speed often comes with a hidden tax.
Move too fast, and you’ll find yourself explaining to a confused CFO why a “small” networking change cost the company $4,000 in a single weekend. I’ve seen teams accidentally provision high-end db.m5.12xlarge instances when they only needed a db.m5.large, simply because they didn’t realize a single variable change would quintuple their spend.
Most cloud cost management is reactive. You wait for the AWS Cost Explorer to update or, worse, for the invoice to arrive at the end of the month. By then, the money is gone. To truly control a budget, we need to shift cost awareness “left”—bringing financial data directly into the developer’s workflow before the infrastructure is even built.
Infracost: A Financial Linter for Your Code
Infracost serves as a bridge between your code and your provider’s pricing API. It isn’t just a tool; it’s a financial safety net. It scans your Terraform files, queries a database of over 3.5 million price points across AWS, Azure, and GCP, and outputs a precise breakdown of your costs. It turns abstract HCL into real dollars and cents.
The real power lies in the Pull Request (PR) integration. Every time a developer pushes code, a bot comments on the PR with a table showing the exact financial impact. If a change adds $500 to the monthly bill, everyone knows immediately. This transparency fosters a culture of accountability without slowing down the development cycle.
How to Set It Up
The implementation follows a simple three-step path: secure an API key, verify the logic locally, and automate the process via GitHub Actions.
1. Register for an API Key
The tool is free for open-source projects and has a generous tier for small teams. To get started, install the CLI and register your account:
brew install infracost
infracost auth register
This command generates an API key in your local configuration. Store this safely; you will need it as a GitHub Secret later.
2. Local Sanity Check
Before automating, run Infracost against your local directory to ensure it parses your modules correctly. If you have a standard main.tf, run:
infracost breakdown --path .
To see how your current changes compare to what is already deployed, use the diff command:
infracost diff --path .
3. Automating with GitHub Actions
Automated cost visibility changes how teams review code. I have applied this approach to production environments with over 50 microservices, and it consistently catches over-provisioning errors before they hit the bill. One developer’s accidental NAT Gateway misconfiguration was caught in seconds, saving us roughly $2,100 a month.
First, add your INFRACOST_API_KEY to your GitHub Repository Secrets. Then, create .github/workflows/infracost.yml:
name: Infracost
on: [pull_request]
jobs:
infracost:
name: Infracost
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout base
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
- name: Generate Infracost baseline
run: |
curl -fsSL https://raw.githubusercontent.com/infracost/infracost/master/scripts/install.sh | sh
infracost breakdown --path . \
--format json \
--out-file /tmp/infracost-base.json
env:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
- name: Checkout PR branch
uses: actions/checkout@v4
- name: Generate Infracost diff
run: |
infracost diff --path . \
--format json \
--compare-to /tmp/infracost-base.json \
--out-file /tmp/infracost.json
env:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
- name: Post Infracost comment
run: |
infracost comment github --path /tmp/infracost.json \
--repo ${{ github.repository }} \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--pull-request ${{ github.event.pull_request.number }} \
--behavior update
env:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
This workflow compares the current state of main against your PR, then posts the results as a comment. It keeps the conversation focused on the actual impact of the code.
Lessons from the Field
Setting up the tool is the easy part. Making it work for a large organization requires a bit more strategy.
Manage Monorepos with Config Files
If your repo contains multiple projects (e.g., staging and production), don’t scan the root. Use an infracost.yml file to define exactly which directories matter:
version: 0.1
projects:
- path: terraform/staging
usage_file: terraform/staging/infracost-usage.yml
- path: terraform/production
usage_file: terraform/production/infracost-usage.yml
Account for Variable Costs
Fixed instance prices are easy to track, but data transfer and Lambda execution costs are invisible in HCL. Use an infracost-usage.yml file to estimate these variables. This bridges the gap between “theoretical” cost and your actual monthly invoice.
Enforce Budget Guardrails
FinOps works best when there are consequences. You can configure your CI to fail if a PR increases costs by more than a set threshold, such as $500. This forces a manual sign-off from a DevOps lead or a manager before expensive resources are provisioned.
Final Thoughts
Cloud management should never be a monthly surprise. By embedding Infracost into GitHub Actions, you turn financial metrics into a standard part of the engineering process. It gives developers the data they need to build responsibly. Instead of locking down the cloud, give your team the tools to use it wisely. Start with visibility, and the cultural shift toward efficiency will follow naturally.

