lesson ── terraform-advanced ── ~14 мин ── 6 шагов
Infracost оценивает стоимость плана до apply. На уроке, без API-токена (для CI требуется зарегистрироваться, для учёбы достаточно показать механику). Делаем breakdown на HCL, видим pricing-таблицу, добавляем resource, видим как меняется estimate.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
infracost --version
В образе уже стоит. Без API-токена работает только help
breakdown требует ключ. Для урока симулируем поведение в
offline-режиме.
✓ Infracost в образе. Версия видна.
Pricing-API понимает только реальные AWS-resources (не LocalStack-emulation). Создадим HCL с типичными production-ресурсами:
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
Это типичный mini-stack. Без API-токена реального plan'а Infracost не сделает, но мы покажем что и как.
✓ HCL с production-shape ресурсами готов.
В offline-режиме оценим через эталонную таблицу AWS. В CI с токеном Infracost сделал бы это автоматически.
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
В реальном Infracost этот breakdown появляется автоматически из plan-файла. Мы видим: $103/mo, это много для просто web+db. Решение: меньший instance, или Savings Plan (Infracost не учитывает, реальная цена ниже).
✓ Breakdown структура понятна. В реальном CI это автоматически.
Поднимаем instance до 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
В CI с настоящим Infracost этот diff появляется как комментарий в PR. Reviewer видит: «PR увеличивает costs на 29.6%». Решает.
Bridge infracost comment github автоматически делает PR-комментарий.
✓ Diff демонстрирует cost-impact PR'а. Это и есть FinOps gate.
cat > budget-gate.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
# В реальном CI: infracost diff --format json > diff.json
# У нас, простая симуляция.
THRESHOLD_PCT=20
CURRENT_DELTA_PCT=29.6 # из предыдущего шага
echo "Current cost delta: ${CURRENT_DELTA_PCT}%"echo "Threshold: ${THRESHOLD_PCT}%"# bc для float-сравнения
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"
Должно показать FAIL, потому что 29.6% > 20%.
В реальном CI: dev либо снижает планируемые costs, либо добавляет label «cost-approved» который сам gate видит и skip'ает (для legitimate cases).
✓ Cost-gate работает. Дороже 20%, apply ждёт явного approve'а.
OpenTofu держит CLI и state совместимыми с Terraform по командам
этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе
сделай backup state и прогон на feature-branch - расхождения
концентрируются в новых фичах (variables в backend,
state-encryption, OCI registry-backed модули). См.
tf-opentofu-parity для полной матрицы.
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
# обновим скрипт под новый delta
sed -i 's/CURRENT_DELTA_PCT=29.6/CURRENT_DELTA_PCT=-14.8/' budget-gate.sh
bash budget-gate.sh
echo "gate exit: $?"
Cost снизился, gate passes. PR merge'абельный.
Реальный FinOps workflow: каждый PR показывает cost-impact в комментарии, threshold блокирует резкий рост.
✓ Cost-as-code gate готов. В реальном CI это infracost + GitHub action.
Реальный setup:
API-токен. Бесплатный с infracost.io. Per-team или per-organization.
Baseline-флоу. На main делаешь infracost breakdown --format json --out-file infracost-base.json, коммитишь.
На каждом PR, infracost diff --compare-to infracost-base.json.
Так видишь дельту относительно текущего prod.
PR-комментарий. GitHub Action infracost-action@v3 берёт
diff.json и постит human-readable таблицу в PR.
Threshold-логика. Конкретный gate-pattern зависит от команды:
Self-hosted snapshot. Для air-gapped или строго privacy: Infracost-API в self-hosted режиме, pricing snapshot обновляется вручную раз в N дней.
Usage-file. Для accuracy указываешь expected usage (Lambda invocations, S3-traffic). Без него, только fixed-cost.
См. tf-cost-infracost.
infracost breakdown --path . → таблица: ресурс / hours per month
/ monthly cost / total. infracost diff сравнивает с baseline.
Без API-key падает, для production-CI требуется зарегистрировать
infracost.io токен.
команды
infracost configure set api_key KEYзаписать токен (бесплатный).infracost breakdown --path .оценка HCL.infracost diff --path . --compare-to base.jsonдельта PR'а к baseline.концепции