lesson ── terraform-advanced ── ~14 мин ── 6 шагов
Infracost estimates the cost of a plan before apply. We work here without an API token (CI needs you to register, but for learning it is enough to show the mechanics). We run a breakdown on the HCL, look at the pricing table, add a resource, and watch the estimate change.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
infracost --version
It is already installed in the image. Without an API token only help
works; breakdown needs a key. For this lesson we simulate the behavior
in offline mode.
✓ Infracost is in the image. You can see the version.
The pricing API understands only real AWS resources, not LocalStack emulation. Let's create HCL with typical production resources:
cd /home/student/cost
cat > main.tf <<'EOF'
resource "aws_instance" "web" {ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
root_block_device {volume_size = 30
volume_type = "gp3"
}
tags = { Name = "web-server" }}
resource "aws_db_instance" "main" {identifier = "main-db"
engine = "postgres"
engine_version = "15"
instance_class = "db.t3.medium"
allocated_storage = 100
username = "admin"
password = "supersecretpass"
skip_final_snapshot = true
}
resource "aws_s3_bucket" "logs" {bucket = "app-logs"
}
EOF
This is a typical mini-stack. Without an API token Infracost cannot run a real plan, but we will show what it does and how.
✓ The HCL with production-shape resources is ready.
In offline mode we estimate using a reference AWS table. In CI with a token Infracost would do this automatically.
cat > /tmp/expected-breakdown.txt <<'EOF'
====================================================================
Project: cost-demo
Name Monthly Qty Unit Cost
====================================================================
aws_instance.web (t3.medium)
├─ Instance usage 730 hours $30.37
├─ root_block_device (gp3, 30GB) 30 GB-months $2.40
aws_db_instance.main (db.t3.medium postgres)
├─ Database instance 730 hours $58.40
├─ Storage (gp2, 100GB) 100 GB-months $11.50
├─ Backup storage - - $0.00
aws_s3_bucket.logs
├─ (no requests/storage in plan) - - $0.00
====================================================================
OVERALL TOTAL $102.67
====================================================================
EOF
cat /tmp/expected-breakdown.txt
With real Infracost this breakdown appears automatically from the plan file. We can see $103/mo, which is a lot for just web+db. The fix: a smaller instance, or a Savings Plan (Infracost does not account for it, so the real price is lower).
✓ The breakdown structure is clear. In real CI this is automatic.
We bump the instance up to t3.large:
sed -i 's/t3.medium/t3.large/' main.tf
cat > /tmp/expected-diff.txt <<'EOF'
~ aws_instance.web
~ Instance usage (t3.medium → t3.large) $30.37 → $60.74 +$30.37
Monthly cost change: +$30.37 (+29.6%)
Total before: $102.67
Total after: $133.04
EOF
cat /tmp/expected-diff.txt
In CI with real Infracost this diff shows up as a comment in the PR. The reviewer sees: "this PR raises costs by 29.6%", and decides.
The bridge infracost comment github posts the PR comment for you.
✓ The diff shows the cost impact of the PR. That is the FinOps gate.
cat > budget-gate.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
# In real CI: infracost diff --format json > diff.json
# Here, a simple simulation.
THRESHOLD_PCT=20
CURRENT_DELTA_PCT=29.6 # from the previous step
echo "Current cost delta: ${CURRENT_DELTA_PCT}%"echo "Threshold: ${THRESHOLD_PCT}%"# bc for float comparison
if (( $(echo "${CURRENT_DELTA_PCT} > ${THRESHOLD_PCT}" | bc -l) )); thenecho "FAIL: cost increase exceeds threshold"
echo "Add 'cost-approved' label to override"
exit 1
fi
echo "PASS: cost within budget"
EOF
chmod +x budget-gate.sh
set +e
./budget-gate.sh
code=$?
set -e
echo "gate exit: $code"
It should print FAIL, because 29.6% > 20%.
In real CI the dev either lowers the planned costs, or adds a "cost-approved" label that the gate itself sees and skips on (for legitimate cases).
✓ The cost gate works. Over 20% and apply waits for an explicit approval.
OpenTofu keeps its CLI and state compatible with Terraform for the
commands in this step: migration usually goes through mv .terraform .terraform.bak; tofu init -upgrade. But on the first switch, back up
the state and run on a feature branch; the differences cluster in the
newer features (variables in the backend, state encryption, OCI
registry-backed modules). See tf-opentofu-parity for the full
matrix.
sed -i 's/t3.large/t3.small/' main.tf
cat > /tmp/expected-diff-2.txt <<'EOF'
~ aws_instance.web
~ Instance usage (t3.medium → t3.small) $30.37 → $15.18 -$15.19
Monthly cost change: -$15.19 (-14.8%)
EOF
cat /tmp/expected-diff-2.txt
# update the script for the new delta
sed -i 's/CURRENT_DELTA_PCT=29.6/CURRENT_DELTA_PCT=-14.8/' budget-gate.sh
bash budget-gate.sh
echo "gate exit: $?"
The cost went down, the gate passes, and the PR is mergeable.
A real FinOps workflow: every PR shows the cost impact in a comment, and the threshold blocks a sharp increase.
✓ The cost-as-code gate is ready. In real CI this is infracost plus a GitHub action.
A real setup:
API token. Free from infracost.io. Per-team or per-organization.
Baseline flow. On main you run infracost breakdown --format json --out-file infracost-base.json and commit it.
On every PR, infracost diff --compare-to infracost-base.json.
That way you see the delta relative to current prod.
PR comment. The GitHub Action infracost-action@v3 takes the
diff.json and posts a human-readable table into the PR.
Threshold logic. The exact gate pattern depends on the team:
Self-hosted snapshot. For air-gapped setups or strict privacy: the Infracost API in self-hosted mode, with the pricing snapshot refreshed by hand every N days.
Usage file. For accuracy you specify the expected usage (Lambda invocations, S3 traffic). Without it, you only get fixed cost.
See tf-cost-infracost.
infracost breakdown --path . gives a table: resource / hours per month
/ monthly cost / total. infracost diff compares against a baseline.
Without an API key it fails, and production CI needs you to register an
infracost.io token.
команды
infracost configure set api_key KEYsave the token (free).infracost breakdown --path .estimate the HCL.infracost diff --path . --compare-to base.jsonthe PR delta against the baseline.концепции