lesson ── terraform-garden ── ~18 мин ── 4 шагов
The pipeline failed on Checkov. The message: "CKV_AWS_53: Ensure S3 bucket has block public ACLs enabled" "CKV_AWS_21: Ensure all data stored in the S3 bucket have versioning enabled"
These are real violations, not false positives. The public access block is
off and versioning is suspended. But the resource is named public_assets,
and the product owner said "this really is a public asset server, we need
public access."
Decide: suppress with a justification or fix it, and either way do not fool the linter with a quick "add comment to suppress."
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
cd /home/student/tf-garden
checkov -d . --quiet --compact 2>&1 | tee /tmp/checkov.log || true
The log should have lines about CKV_AWS_53 (block public acls) and CKV_AWS_21 (versioning). Right now both checks are FAILED.
This is not a linter bug: the HCL really did set
block_public_acls = false and status = "Suspended".
✓ Violations confirmed. Now, the decision.
Versioning Suspended is almost always a mistake. Even for a public asset server: versions let you recover something deleted by accident. Fix it:
resource "aws_s3_bucket_versioning" "public_assets" {bucket = aws_s3_bucket.public_assets.id
versioning_configuration {status = "Enabled"
}
}
Replace the block in main.tf. You can use sed:
sed -i 's/status\s*=\s*"Suspended"/status = "Enabled"/' main.tf
✓ Versioning is on. This rule will not fail again.
Here the product owner is right, the bucket is for public assets, public
access is required. But a plain #checkov:skip=CKV_AWS_53 with no reason
is bad. Write it with a justification:
Replace the aws_s3_bucket_public_access_block block with:
# checkov:skip=CKV_AWS_53: bucket serves public marketing assets; public-access required by product
# checkov:skip=CKV_AWS_54: same reason, public ACLs intentional for assets
# checkov:skip=CKV_AWS_55: see above
# checkov:skip=CKV_AWS_56: see above
resource "aws_s3_bucket_public_access_block" "public_assets" {bucket = aws_s3_bucket.public_assets.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
This is an explicit sign-off: "I know what I am doing, because X." The next reviewer reads it and either agrees or reopens the discussion on the merits.
The justification in the comment matters more than the skip itself. Without a reason it is tech debt with a green CI, which is worse than a red CI.
✓ A suppression with a reason is in place. This is no longer a cheat.
checkov -d . --quiet --compact 2>&1 | tee /tmp/checkov2.log || true
Before: 2 FAILED, now 0 (or the same checks marked SKIPPED, with your comment). CI turns green.
If you did a third thing and suppressed CKV_AWS_21 (versioning), that is a cheat: the versioning rule is relevant even for a public bucket. Recheck the versioning step.
✓ The pipeline is clean. The linter is quiet, and the resource is as safe as the context allows.
Checkov and Trivy work with plan.json and HCL, and both tools are provider-agnostic. An OpenTofu plan is just as valid to them as a Terraform plan. In real CI, run both, because they find different sets of issues. See tf-opentofu-parity and tf-checkov.
When the scanner complains, you have three options. Fix it (if the rule is right), suppress it (if the resource really is an exception), fix it a different way (if the rule is technically right but the context differs). A bare skip with no reason is a fourth, and it is not an option.
команды
checkov -d . --quietrun only the failed checks; --quiet drops the noise from passed onescheckov -d . --check CKV_AWS_21target a single check by its IDcheckov -d . --download-external-modules true --framework terraform_plan -f plan.jsonscan plan.json instead of HCL, more accurate, no false hits on dataконцепции