CircleCI Terraform cost estimation: a cost job on every PR
Add a CircleCI job that runs after terraform plan, prices the plan JSON, and comments the monthly cost on the pull request, failing the build past a budget. Here is how it fits a config.yml workflow and keeps pipelines fast.
Quick answer
Add a CircleCI job after terraform plan that converts the plan to JSON and runs the estimator (for example c3x estimate --path plan.json), comments the monthly cost on the pull request, and exits non-zero past a budget so the required workflow fails. It reuses the plan you already generate and needs no cloud credentials to estimate.
CircleCI runs your Terraform validation on every change, so it is the natural place to add cost. The pattern is the same as every other CI system: plan, convert the plan to JSON, price it, comment, and gate on a budget, the shift-left idea from estimating cost before deploy.
Estimate from the plan JSON
In a job, run terraform plan -out=tf.plan, then terraform show -json tf.plan > plan.json, then the estimator against plan.json. The resolved plan is the most accurate input, for the reasons in plan JSON cost estimation.
Wire it into config.yml
Add a cost job to your workflow that depends on the plan job (or reruns the plan), executes the estimator, and posts the result. CircleCI orbs and the stored project credentials let the job comment on the pull request via the GitHub or Bitbucket API. Because estimation needs only the plan file, the job requires no cloud credentials.
Gate on a budget
Have the estimator exit non-zero when the monthly total, or the delta versus the base branch, crosses a threshold. A failing job fails the workflow, and if that workflow is a required check the over-budget change cannot merge, the budget-guardrail pattern in CircleCI terms.
Keep it fast
Cache the Terraform install and provider plugins between runs, reuse the plan artifact rather than planning twice, and run the cost job in parallel with other validation. The estimate itself runs in seconds. The same flow works in GitHub Actions, GitLab CI, and Jenkins; only the config syntax and comment API differ.
FAQ
Where does cost estimation go in a CircleCI pipeline?
In a job after terraform plan, on pull-request builds. Generate the plan, convert it to JSON, and price it. Because the plan resolves variables and modules, its JSON is the most accurate input for the estimate.
How do I comment the cost on a PR from CircleCI?
Use the stored project credentials and the GitHub or Bitbucket API (directly or via an orb) to post the estimate as a pull-request comment. Comment the monthly total and the delta versus the base branch so reviewers see cost next to the diff.
How do I fail a CircleCI build when a PR is over budget?
Have the estimator exit non-zero past a budget threshold, which fails the cost job and the workflow. Make that workflow a required status check so an over-budget change cannot merge until it is fixed or approved.
Does CircleCI cost estimation need cloud credentials?
The plan step needs your existing cloud credentials; the estimation step does not. It reads the plan JSON and prices it against a catalog, so it never calls your cloud account and can run on a restricted executor.
Will adding cost estimation slow my CircleCI pipeline?
No. A static estimate runs in seconds and reuses the plan you already produce. Cache the Terraform install and provider plugins, and run the cost job in parallel with other validation to keep the pipeline fast.
Does C3X work with CircleCI?
Yes. C3X is a CLI that reads your Terraform plan and prices it against a live catalog, so it runs in any CircleCI job. Comment the output on the PR and gate on a budget exactly as with any other CI system.
What to do next
Add the job to one project and watch the cost comment appear. C3X reads your Terraform plan, prices your resources against a live catalog, and gates on a budget. Start with the quickstart and the CI/CD guide.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.