Cheat sheet — IaC Security Scanning (Checkov / tfsec)¶
Companion to Module 03 — IaC Security Scanning · CC BY 4.0 — print it, pin it, share it.
Last reviewed: 2026-07
Checkov — scan Terraform / IaC¶
checkov -d . # scan a directory tree of IaC
checkov -f main.tf # scan a single file
checkov -d . --compact # one line per check, no code snippets
checkov -d . -o json # machine-readable (also: -o sarif, -o cli, -o junitxml)
checkov -d . --framework terraform # limit to one IaC framework (also: cloudformation, kubernetes…)
checkov --list # every built-in policy and its ID
Scan a plan, not just source — catches values only known after interpolation:
terraform plan -out tf.plan
terraform show -json tf.plan > plan.json
checkov -f plan.json # scan the resolved plan
Suppress a finding — with a rationale, never silence¶
resource "aws_s3_bucket" "public_site" {
# checkov:skip=CKV_AWS_20:This bucket is a public static site by design — reviewed 2026-07
acl = "public-read"
}
checkov -d . --skip-check CKV_AWS_20 # skip a check globally (blunt — prefer inline skip)
checkov -d . --check CKV_AWS_18 # run ONLY specific checks
tfsec — the second opinion¶
tfsec . # scan current directory
tfsec . --format sarif # SARIF for GitHub code-scanning upload
tfsec . --minimum-severity HIGH # only HIGH and CRITICAL fail the run
Inline ignore (scoped to the next block, with an expiry):
Wire it as a CI gate (exit codes are the contract)¶
# GitHub Actions step — non-zero exit fails the job and blocks the merge
- name: checkov
run: checkov -d . --compact --soft-fail=false # soft-fail=false → findings fail the build
| exit code | meaning |
|---|---|
0 |
no failed checks — gate passes |
1 |
at least one failed check — gate blocks |
Gotchas worth remembering¶
- A passing scan is not a secure config — it's an absence of known-bad patterns. Checkov can't tell the port you opened on purpose from the one that's a breach. The scanner is a fast junior reviewer; you still own the verdict.
- Suppress with a reason, never with
--soft-faileverywhere. An inlinecheckov:skip=ID:whydocuments the risk decision in the diff and survives review; a blanket soft-fail turns the gate into decoration and the next real finding sails through. - Scan the plan JSON, not only the
.tf. Values that come from variables or interpolation are(known after apply)in source — the open CIDR only appears in the resolved plan. - Exit code is the gate, not the pretty output. In CI, assert on the exit code;
--soft-failhides the failure from your pipeline while still printing scary red text nobody blocks on. - Run two scanners. Checkov and tfsec have different rule coverage — each catches things the other misses. Fail the build if either does.
Comments
Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).