Terraform cost estimation in GitLab CI: estimate and gate on every MR
Add a GitLab CI job that estimates Terraform cost on every merge request, posts the number as an MR note, and fails the pipeline over budget. Works on self-hosted and air-gapped GitLab. No apply needed.
Quick answer
Add a job to .gitlab-ci.yml that installs C3X and estimates your Terraform cost on every merge request — posting the monthly cost and the diff as an MR note, and failing the pipeline when a budget is exceeded. No apply, no outbound network required (offline snapshot for air-gapped GitLab), and it runs in seconds alongside your plan job.
The best time to catch a costly infrastructure change is in the merge request, not on the invoice. GitLab CI makes this straightforward: a single cost job that estimates the Terraform in the MR, shows reviewers the number, and blocks the merge if it blows the budget.
A minimal cost job
cost_estimate:
stage: test
image: ghcr.io/c3xdev/c3x:latest
script:
- c3x estimate --path . --format table
# Fail the pipeline if monthly cost exceeds the budget
- c3x estimate --path . --budget 2000
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"The job runs on merge requests, prints the estimate, and exits non-zero if the monthly cost crosses the threshold — turning the budget into a hard gate. Drop the --budget line if you only want visibility.
Show the cost on the merge request
Beyond pass/fail, you can post the estimate as an MR note so reviewers see the cost impact inline — the new database, the scaled node pool, the extra NAT gateway — next to the diff that introduced it. Pair the comment with the budget gate and you get both awareness and enforcement, the pattern described in budget guardrails in CI.
It runs before apply
Cost estimation is static — C3X reads the configuration or a terraform plan output and prices it without provisioning anything. That's the point: the number lands in the MR while the change is still reviewable, the same pre-deploy workflow as estimating AWS costs from Terraform, here wired into GitLab instead of a local run.
Self-hosted and air-gapped GitLab
C3X is a single binary (and a container image), so it runs on GitLab.com shared runners and self-hosted runners equally. For regulated or air-gapped GitLab, it can use an offline pricing snapshot so the cost job needs no outbound network — see air-gapped cost estimation.
FAQ
How do I add Terraform cost estimation to GitLab CI?
Add a job to .gitlab-ci.yml that installs C3X and runs it against your Terraform (or a generated plan), then surfaces the estimate. You can post the result as a merge request note and fail the pipeline if the estimated monthly cost exceeds a budget — all without applying any infrastructure.
Can the pipeline fail when a change is too expensive?
Yes. Run C3X with a budget policy in the cost job; if the estimated monthly cost (or the delta versus the target branch) exceeds your threshold, the job exits non-zero and the pipeline fails, blocking the merge until someone reviews the cost. It's a hard guardrail, not just a comment.
Does it work with merge request comments?
Yes. The cost job can post a note on the merge request with the estimated monthly cost and the diff against the base branch, so reviewers see the cost impact inline. Combine that with a budget gate for both visibility and enforcement.
Do I need to run terraform apply in CI to estimate cost?
No — and you shouldn't. Cost estimation runs before apply: C3X reads the Terraform configuration or a terraform plan output and prices it statically. The whole point is to see the cost in the merge request, before anything is provisioned.
Will this slow down my pipeline?
Barely. The cost job installs a small binary and runs a static estimate in seconds. It can run in parallel with your plan/validate jobs, so it adds visibility and a budget gate without meaningfully extending pipeline time.
Does C3X support self-hosted GitLab?
Yes. C3X is a self-contained binary (also available as a container image), so it runs on GitLab.com shared runners and self-hosted runners alike. For air-gapped GitLab, C3X can use an offline pricing snapshot so the cost job needs no outbound network.
What to do next
Add the cost job to your .gitlab-ci.yml and every merge request gets a cost estimate and a budget gate. The CI/CD guide has copy-paste configurations, and the quickstart gets you a local estimate first so you know what the pipeline will report.
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.