# Checkov: статический анализ HCL _Security · TerraformLab Knowledge Base_ **TL;DR:** Checkov, Python-сканер от Prisma Cloud, проверяет `.tf` и `plan.json` против ~2000 встроенных правил (CKV_AWS_*, CKV_K8S_*, etc.). Запускается на HCL до plan'а (быстрее) или на JSON-plan (богаче, видит вычисленные значения). Suppressions делаются комментарием в HCL или в файле конфигурации; baseline-файл фиксирует найденные issues как «приемлемые на сейчас», чтобы новые сразу ломали CI. ## Что Checkov делает Checkov берёт каталог с `.tf` файлами и проходит по нему ~2000 встроенных правил. Каждое правило, конкретная проверка («S3 bucket has encryption», «IAM policy not wildcard»). Каждое имеет идентификатор: `CKV_AWS_19`, `CKV_K8S_8`, и т.д. По идентификатору быстро находишь документацию. Поддерживает: Terraform (HCL и `plan.json`), CloudFormation, Kubernetes manifests, Helm, Dockerfile, GitHub Actions, и ещё с десяток форматов. Здесь, про Terraform. ## Минимальный запуск ```bash checkov --directory . ``` Вывод (упрощённо): ``` Check: CKV_AWS_19: "Ensure all data stored in the S3 bucket is securely encrypted at rest" FAILED for resource: aws_s3_bucket.logs File: /main.tf:1-7 Check: CKV_AWS_53: "Ensure S3 bucket has block public ACLs enabled" PASSED for resource: aws_s3_bucket.logs ... Passed checks: 14, Failed checks: 3, Skipped checks: 0 ``` Exit-code: 0, все pass, 1, есть failed. CI ставит exit-check на job. ## HCL-режим vs plan.json-режим | Режим | Команда | Плюсы | Минусы | |---|---|---|---| | HCL | `checkov -d .` | Не нужен terraform init | Видит только статически заданные значения; intercolation через `var.x` иногда теряется | | plan.json | `checkov -f plan.json` | Видит вычисленные значения, computed-атрибуты, локали раскрыты | Требует init+plan, медленнее | ```bash # plan.json режим terraform init -backend=false terraform plan -out=plan.tfplan terraform show -json plan.tfplan > plan.json checkov -f plan.json ``` Production-pipeline обычно использует plan.json, он точнее. ## Suppression: пропустить правило Иногда правило неприменимо. Например, `aws_s3_bucket.web_assets` публичный по дизайну, отключаем CKV_AWS_53 («block public ACLs»). **Вариант 1: inline-комментарий.** Прямо над ресурсом: ```hcl # checkov:skip=CKV_AWS_53: Public on purpose, see ADR-014 resource "aws_s3_bucket" "web_assets" { bucket = "linuxlab-public-assets" } ``` Формат: `checkov:skip=: <причина>`. Причина обязательна, без неё checkov не примет suppression. **Вариант 2: глобальный skip.** Если правило вообще не подходит проекту (например, использование IMDSv2 невозможно в твоей сети): ```bash checkov -d . --skip-check CKV_AWS_79 ``` Лучше зафиксировать в `.checkov.yml`: ```yaml # .checkov.yml skip-check: - CKV_AWS_79 ``` Запуск автоматически подхватит файл. **Вариант 3: baseline.** «Зафиксировать текущий уровень фейлов, ломать CI только на новых». Полезно для legacy. ```bash checkov -d . --create-baseline # генерирует .checkov.baseline с текущими findings ``` Потом в CI: ```bash checkov -d . --baseline .checkov.baseline ``` Старые findings не fail'ят, новые, да. Постепенно чистишь baseline, поднимаешь планку. См. [tf-checkov](/terraform/kb/tf-checkov.md) usage в production. ## Конфигурационный файл `.checkov.yml` в корне репо: ```yaml framework: - terraform - terraform_plan output: - sarif # для GitHub Security tab - cli skip-check: - CKV_AWS_79 soft-fail-on: - CKV_AWS_18 # warning, не error download-external-modules: true # ходить за git/registry-модулями ``` ## Скан конкретных ресурсов или checks Только check'и определённого фреймворка: ```bash checkov -d . --framework terraform ``` Только одно правило (полезно для отладки): ```bash checkov -d . --check CKV_AWS_19 ``` Несколько: ```bash checkov -d . --check CKV_AWS_19,CKV_AWS_20,CKV_AWS_53 ``` ## Custom policies, свои правила Если нужно правило, которого нет («все бакеты должны иметь тег CostCenter»), пишешь Python-класс: ```python # custom_policies/check_costcenter_tag.py from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck from checkov.common.models.enums import CheckCategories, CheckResult class CostCenterTagRequired(BaseResourceCheck): def __init__(self): super().__init__( name="Ensure CostCenter tag is set", id="CKV_CUSTOM_1", categories=[CheckCategories.GENERAL_SECURITY], supported_resources=["aws_s3_bucket", "aws_instance", "aws_db_instance"], ) def scan_resource_conf(self, conf): tags = conf.get("tags", [{}])[0] if "CostCenter" in tags: return CheckResult.PASSED return CheckResult.FAILED check = CostCenterTagRequired() ``` Подключение: ```bash checkov -d . --external-checks-dir ./custom_policies ``` Для большинства команд кастомные правила, это перебор; начни с встроенных и suppression'ов. ## SARIF и GitHub Security Checkov умеет выгружать SARIF, GitHub понимает этот формат и показывает findings в вкладке Security твоего репо. ```bash checkov -d . -o sarif > checkov.sarif ``` Загрузка через GitHub Action: ```yaml - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: checkov.sarif ``` Каждый finding, отдельный alert с location в коде и описанием правила. ## Подводные камни - **Checkov ловит много, но не всё.** Правила покрывают известные шаблоны. Бизнес-логику и cross-resource политики (OPA/Rego/terraform-compliance) он не заменяет. - **Suppression без причины, антипаттерн.** `checkov:skip=CKV_AWS_19` без объяснения = баг. Reviewer не знает, зачем пропустили. Reasoning обязателен и должен ссылаться на ADR/incident. - **HCL-режим теряет вычислимые значения.** `var.encryption_enabled ? "AES256" : null`, checkov на HCL может увидеть только null. Plan-mode раскрывает это и проверяет фактическое значение. - **`--download-external-modules` ходит в интернет.** В air-gapped CI отключай или предзагружай. В обычном, без него внешние модули остаются непросканированными. - **Версии checkov ломают совместимость.** Между релизами появляются новые правила (новые fails в CI без изменения кода), переименовываются ID'шки. Пиннуй версию в CI (`checkov==3.2.402`), обновляй сознательно. - **Checkov не статический анализ HCL целиком.** Не проверит синтаксис (`terraform validate`), не проверит стиль (`terraform fmt`), не проверит tflint-правила. Это **дополнение** к ним, не замена. ## См. также в LinuxLab - [bash-strict-mode](/courses/linux/kb/bash-strict-mode), без `set -euo pipefail` пайпы вокруг `checkov` могут глотать ненулевой exit. Если `checkov | tee` отрабатывает, а CI всё равно зелёный, это `tee` проглотил код возврата. - [xargs-and-find-exec](/courses/linux/kb/xargs-and-find-exec), для pre-commit hooks с `find . -name '*.tf' | xargs checkov -f` важно помнить `xargs -r` чтобы пустой ввод не запустил `checkov` с нулём аргументов. ## Команды ```bash pip install checkov==3.2.402 ``` Установка с pinned-версией для воспроизводимости. ```bash checkov -d . ``` Скан HCL в текущем каталоге. Быстро, ок для предкоммита. ```bash checkov -f plan.json ``` Скан plan.json после terraform show -json. Точнее, чем HCL-режим. ```bash checkov -d . --skip-check CKV_AWS_79 --soft-fail-on CKV_AWS_18 ``` Пропустить CKV_AWS_79, для CKV_AWS_18: warning без exit 1. ```bash checkov -d . --create-baseline ``` Зафиксировать текущие findings как acceptable. CI потом ломается только на новых. ## См. также - [Trivy и tfsec: security-сканеры HCL](/terraform/kb/tf-trivy-tfsec.md) - [OPA + Rego, policy as code для Terraform plan](/terraform/kb/tf-policy-as-code.md) - [terraform-compliance: BDD-проверки на plan-файл](/terraform/kb/terraform-compliance.md) - [sensitive в Terraform: про логи, не про шифрование](/terraform/kb/tf-sensitive.md)