# Trivy и tfsec: security-сканеры HCL
_Security · TerraformLab Knowledge Base_
**TL;DR:** tfsec, оригинальный security-сканер от Aqua, написан на Go,
быстрый. С 2023 года слит в Trivy, у того теперь модуль `trivy
config` для IaC, та же база правил (AVD-* идентификаторы).
Альтернатива Checkov: меньше правил, но быстрее, бинарь без
зависимостей. В CI обычно: либо Trivy/tfsec, либо Checkov, не оба.
## Что они и почему два
**tfsec** появился в 2019, Go-приложение от Aqua Security, security-сканер
под Terraform. Быстрый (десятки мс на средний проект), single-binary,
без Python-зависимостей.
В 2023 Aqua слила tfsec в **Trivy**, мульти-инструмент того же вендора
(сканер контейнерных образов, SBOM, IaC). Теперь IaC-сканинг, это
`trivy config
`. Правила и движок те же, что в tfsec. Сам tfsec
как самостоятельный проект deprecated, но команды и идентификаторы
правил часто остались в legacy-пайплайнах.
Правило это: используешь Trivy. Если ты на legacy-pipeline с tfsec
миграция тривиальна. См. [tf-trivy-tfsec](/terraform/kb/tf-trivy-tfsec.md) раздел про миграцию.
## Запуск Trivy
```bash
trivy config .
```
Сканирует все поддерживаемые форматы в текущей директории: Terraform,
CloudFormation, Kubernetes, Dockerfile.
Вывод:
```
Tests: 28 (SUCCESSES: 25, FAILURES: 3, EXCEPTIONS: 0)
Failures: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 1, CRITICAL: 0)
main.tf (terraform)
AVD-AWS-0086 (HIGH): No public access block so not blocking public acls
...
AVD-AWS-0089 (MEDIUM): S3 Bucket does not have logging enabled.
...
```
Только Terraform:
```bash
trivy config --skip-dirs node_modules --type terraform .
```
Конкретные severity:
```bash
trivy config --severity HIGH,CRITICAL .
```
Exit-code: 0 при no-issues по умолчанию. `--exit-code 1` ставит exit 1
при любых findings (для CI).
## tfsec → trivy migration
| tfsec | trivy |
|---|---|
| `tfsec .` | `trivy config .` |
| `tfsec --exclude aws-s3-encryption-customer-key` | `trivy config --ignore-policy aws-s3-encryption-customer-key` |
| `tfsec --tfvars-file dev.tfvars` | `trivy config --tf-vars dev.tfvars` |
| `.tfsec/config.yaml` | `trivy.yaml` |
| finding-ID: AWS001 | finding-ID: AVD-AWS-0086 (новые) |
Правила те же, но переименовали идентификаторы. Если был
`tfsec:ignore:AWS001` в HCL, заменить на `trivy:ignore:AVD-AWS-0086`.
## Suppression
Inline:
```hcl
#trivy:ignore:AVD-AWS-0089
resource "aws_s3_bucket" "logs" {
bucket = "no-logging-on-purpose"
}
```
Несколько правил:
```hcl
#trivy:ignore:AVD-AWS-0089
#trivy:ignore:AVD-AWS-0086
resource "aws_s3_bucket" "public_assets" {
# ...
}
```
Файл-конфиг `trivy.yaml`:
```yaml
ignored-policies:
- AVD-AWS-0086
```
Trivy/tfsec **не требует** причины в комментарии, это отличие от Checkov.
Команды часто добавляют convention типа `#trivy:ignore:AVD-AWS-0086 #
see ADR-014` для трассируемости.
## Trivy/tfsec vs Checkov
| Аспект | Trivy/tfsec | Checkov |
|---|---|---|
| Язык | Go | Python |
| Установка | Один бинарь (curl + chmod) | pip install (Python-env) |
| Скорость | Быстрее (миллисекунды) | Заметно медленнее (секунды на средний проект) |
| Правила | ~150 для Terraform | ~600 для Terraform |
| Покрытие cloud-провайдеров | AWS, GCP, Azure, Oracle, DigitalOcean | те же + Kubernetes-policies |
| Custom-rules | YAML или Rego | Python-class или YAML (с 3.0) |
| SARIF-output | Да | Да |
| Поддерживается | Да (через Trivy) | Да (Prisma Cloud) |
Реалистично: оба ловят похожие классы проблем. Checkov шире, Trivy
быстрее. Многие команды берут что-то одно, чтобы не плодить
совпадающие suppression'ы. Если выбираешь, Trivy для CI-скорости,
Checkov для policy-spec'ов.
## CI-интеграция
```yaml
# .github/workflows/security.yml
jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy config scan
uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: config
scan-ref: .
severity: HIGH,CRITICAL
exit-code: 1
format: sarif
output: trivy-results.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
```
Получишь findings во вкладке Security и обязательный fail на
HIGH/CRITICAL.
## Custom-rules через Rego
Trivy умеет читать пользовательские правила в Rego (тот же язык, что у
OPA, см. [tf-policy-as-code](/terraform/kb/tf-policy-as-code.md)):
```rego
# policies/costcenter.rego
package custom.costcenter
__rego_metadata__ := {
"id": "AVD-CUSTOM-001",
"title": "CostCenter tag required",
"severity": "MEDIUM",
}
__rego_input__ := {
"selector": [{"type": "defsec", "subtypes": [{"service": "s3"}]}],
}
deny[res] {
bucket := input.aws.s3.buckets[_]
not bucket.tags.CostCenter
res := {
"msg": sprintf("S3 bucket %s missing CostCenter tag", [bucket.name.value]),
}
}
```
Подключение:
```bash
trivy config --config-policy ./policies .
```
## Подводные камни
- **AVD-идентификаторы, нестабильные.** Раньше были AWS001, потом
переименовали в AVD-AWS-0086. Старые tfsec-suppress'ы продолжат
«работать» (no-op), но реально правило теперь под другим именем.
Перепроверь после миграции.
- **Trivy сканирует всё подряд по дефолту.** В одной директории с
Dockerfile и .tf он сделает оба скана. Если хочешь только Terraform
`--type terraform` (или `--scanners config` для всех IaC форматов).
- **Severity, мнение вендора.** Что-то «MEDIUM» по Trivy может быть
«CRITICAL» для твоей среды. Не доверяй вендорной градации слепо;
делай свой `--severity`-фильтр или soft-fail на низких уровнях.
- **`trivy.yaml` vs CLI-флаги, конфликты.** Если оба, CLI выигрывает.
Команды путают; держи конфиг в одном месте.
- **Не покрывает state.** Это сканер сорсов, не runtime. Что уже задеплоено
и работает, не его задача. Для drift'а, [tf-drift-detection](/terraform/kb/tf-drift-detection.md);
для скана уже созданного, Trivy умеет AWS-account-scan, но это
другой режим.
- **Suppression без причины, болото.** Trivy не требует ёе, в отличие
от Checkov. Командой добавь convention: `#trivy:ignore:X, reason`.
Без этого через полгода никто не знает, почему `ignore`.
## Команды
```bash
trivy config .
```
Сканирует все .tf, .yaml, Dockerfile в текущей директории. Default-severity: всё кроме UNKNOWN.
```bash
trivy config --severity HIGH,CRITICAL .
```
Только высокие. Стандартный режим CI gate.
```bash
trivy config --tf-vars dev.tfvars .
```
Подсунуть var-файл: частичная раскрутка интерполяций.
```bash
trivy config --format sarif --output trivy.sarif .
```
Output для GitHub Security tab.
## См. также
- [Checkov: статический анализ HCL](/terraform/kb/tf-checkov.md)
- [OPA + Rego, policy as code для Terraform plan](/terraform/kb/tf-policy-as-code.md)
- [sensitive в Terraform: про логи, не про шифрование](/terraform/kb/tf-sensitive.md)
- [Секреты и Terraform state: где хранить и как читать](/terraform/kb/tf-secrets-in-state.md)