lesson ── terraform-production ── ~13 мин ── 5 шагов
Checkov, сканер от Prisma Cloud, проверяет HCL и plan.json против ~2000 правил безопасности. На этом уроке прогонишь его на нечистом HCL, увидишь findings, попробуешь suppression и baseline.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
cd /home/student/tf-checkov
cat > main.tf <<'EOF'
resource "aws_s3_bucket" "logs" {bucket = "linuxlab-checkov-demo"
}
resource "aws_s3_bucket" "data" {bucket = "linuxlab-checkov-data"
}
EOF
Два бакета без encryption, без versioning, без public access block классический набор сомнительных умолчаний.
Запусти checkov:
checkov -d . --quiet --no-guide 2>&1 | head -50
Должны быть FAILED по CKV_AWS_18, CKV_AWS_19, CKV_AWS_21, CKV_AWS_53 и т.д., для обоих бакетов.
✓ Checkov нашёл проблемы. Сейчас исправим часть и подавим остальные.
cat >> main.tf <<'EOF'
resource "aws_s3_bucket_server_side_encryption_configuration" "logs" {bucket = aws_s3_bucket.logs.id
rule { apply_server_side_encryption_by_default {sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_versioning" "logs" {bucket = aws_s3_bucket.logs.id
versioning_configuration {status = "Enabled"
}
}
resource "aws_s3_bucket_public_access_block" "logs" {bucket = aws_s3_bucket.logs.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
EOF
checkov -d . --quiet --no-guide 2>&1 | tail -10
Должно быть меньше fails, бакет logs теперь чистый. data
остался unfixed для следующего шага.
✓ Бакет logs прошёл. Бакет data ещё нет.
data бакет, нарочно публичный (например, для web-assets). Это
ADR-ed decision. Подавляем только public-access-блокировку,
остальное добавляем.
cat >> main.tf <<'EOF'
resource "aws_s3_bucket_server_side_encryption_configuration" "data" {bucket = aws_s3_bucket.data.id
rule { apply_server_side_encryption_by_default {sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_versioning" "data" {bucket = aws_s3_bucket.data.id
versioning_configuration {status = "Enabled"
}
}
EOF
Теперь добавь suppression перед data-бакетом:
sed -i '/resource "aws_s3_bucket" "data"/i\
# checkov:skip=CKV_AWS_53: Public on purpose (web assets), ADR-014\
# checkov:skip=CKV_AWS_54: Public on purpose, ADR-014\
# checkov:skip=CKV_AWS_55: Public on purpose, ADR-014\
# checkov:skip=CKV_AWS_56: Public on purpose, ADR-014' main.tf
checkov -d . --quiet --no-guide 2>&1 | tail -10
Suppressions срабатывают только для тех правил, что указаны явно. Если правило не в списке, оно всё ещё работает.
✓ Suppression с causes добавлены. Reviewer видит причину.
В реальном legacy-проекте сразу починить всё нельзя. Baseline фиксирует текущие findings как «приемлемые», ломает CI только на новых.
Создай baseline:
checkov -d . --create-baseline --quiet --no-guide 2>&1 || true
ls -la .checkov.baseline
cat .checkov.baseline | head -30
Сейчас в baseline, все текущие findings (если ещё остались). Запусти с baseline'ом:
checkov -d . --baseline .checkov.baseline --quiet --no-guide 2>&1 | tail -10
Должно показать что failed checks упали, те что в baseline. Если добавишь новый плохой ресурс, он не в baseline, CI его поймает.
✓ Baseline создан. В CI с этого момента, только новые findings.
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 для полной матрицы.
Производственный pipeline-shell:
cat > checkov-ci.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
checkov \
-d . \
--baseline .checkov.baseline \
--quiet \
--no-guide \
--soft-fail-on CKV_AWS_2 \
--skip-check CKV_AWS_999
echo "Checkov gate passed."
EOF
chmod +x checkov-ci.sh
./checkov-ci.sh
Что флаги делают:
--baseline, игнорировать текущие.--quiet / --no-guide, короткий вывод без помощи.--soft-fail-on, для этого правила warning, не error.--skip-check, глобально пропустить (используй редко).Exit-код 0, gate passed. CI продолжает.
✓ Gate готов. На любом новом security-fail PR будет красным.
Checkov, это шаблонные правила. Он не покрывает:
Cross-resource policy. «Lambda и RDS в одной VPC» Checkov не знает. Это OPA-уровень.
Бизнес-логику. «Все бакеты с тегом CostCenter», можно custom-rule написать, но проще через OPA.
Runtime-проблемы. Если HCL правильный, но AWS отказывает Checkov молчит.
Drift. Что в облаке стало plain-text, другой инструмент.
Стек проверок production-репо:
terraform fmt / validate / tflint, формат и синтаксис.checkov или trivy config, шаблонные security..tftest.hcl, функциональные тесты модулей.Один Checkov, это 20% покрытия. Остальное, другие слои.
Checkov: checkov -d . на HCL, checkov -f plan.json на plan.
Suppression, #checkov:skip=CKV_AWS_X: reason в HCL.
Baseline, --create-baseline фиксирует current findings;
дальше ломается только на новых.
команды
checkov -d .сканировать HCL в директории.checkov -d . --check CKV_AWS_19только одно правило.checkov -d . --create-baselineсгенерировать .checkov.baseline.checkov -d . --baseline .checkov.baselineзапуск с baseline, новые findings ломают CI, старые нет.концепции