CoursesInfrastructure as Code & automationAdvanced · Policy & scanning

Scanning: Checkov, tfsec/Trivy, Terrascan, KICS

Catch misconfigurations before apply.

Advanced14 min · lesson 18 of 23

Alongside custom policy, a family of ready-made scanners checks your IaC for known misconfigurations out of the box — hundreds of security best-practices encoded so you do not have to write each rule yourself. Point them at your Terraform, CloudFormation, Kubernetes, or Dockerfiles and they flag insecure settings: unencrypted storage, public access, missing logging, over-broad IAM, and more. Where policy-as-code enforces your specific org rules, these scanners bring a large baseline of general security knowledge for free.

terminal
$ checkov -d . # scan all IaC in this directory
Check: CKV_AWS_20: "S3 Bucket has an ACL defined which allows public access"
FAILED for resource: aws_s3_bucket.data
File: /main.tf:14-19
$ tfsec . # (now part of Trivy) — Terraform-focused scanner
$ trivy config . # Trivy scans IaC misconfigs (and much more)
$ terrascan scan -i terraform # another scanner, policy-driven
$ kics scan -p . # KICS: broad IaC coverage

The main scanners

Several tools cover this space with overlapping strengths. Checkov (by Prisma/Bridgecrew) is popular and broad, covering Terraform, CloudFormation, Kubernetes, Helm, and more with hundreds of built-in checks. tfsec was a Terraform-focused scanner now merged into Trivy, which has become a one-stop tool (it scans images, filesystems, AND IaC config). Terrascan and KICS (by Checkmarx) are other well-known scanners with their own rule sets. You do not need all of them — pick one or two that cover your stack and integrate cleanly.

Gate the pipeline, tune the noise

The workflow mirrors image scanning from the CI/CD course: run the scanner in the pipeline on every change, report everything for visibility, and fail the build on the severities that matter. Expect initial noise — scanners flag many findings on an existing codebase — so triage: fix the real issues, suppress confirmed false positives with inline annotations (a documented skip, not a blanket disable), and gate on high/critical. A scanner tuned to be trusted stays enabled; one that blocks every merge with low-value findings gets disabled within a sprint.

.gitlab-ci.yml
iac-scan:
image: bridgecrew/checkov:latest
script:
- checkov -d . --compact --soft-fail-on LOW # report low, fail on higher
# inline suppression (documented) next to the resource:
# #checkov:skip=CKV_AWS_20:public access is required for this static site
Scanners find the known; they are not the whole of security
IaC scanners catch a huge amount of common misconfiguration cheaply — run them everywhere. But they check against a catalog of known patterns, so they miss logic flaws, business-context risks, and anything novel, and a clean scan does not mean "secure." Combine them with custom policy-as-code for your org-specific rules, human review for design, and the runtime controls from the other courses. And keep the scanner itself updated and pinned — an outdated ruleset misses recent issues, and an unpinned scanner is an unreproducible gate.