Terrascan
Terrascan = static code analyzer สำหรับ IaC โดย Tenable — รองรับ Terraform, K8s, Helm, Kustomize, Dockerfile
ทำไม Terrascan?
- 🔍 500+ pre-built policies ครอบคลุม CIS, GDPR, HIPAA, PCI
- 🆓 Open-source
- 🧩 Custom policies ผ่าน Rego (OPA)
- 🌐 Multi-cloud: AWS, Azure, GCP, K8s
- 🎯 รองรับ remote modules
Install
# macOS
brew install terrascan
# Linux
curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E 'https://.+?_Linux_x86_64.tar.gz')" -o terrascan.tar.gz
tar -xf terrascan.tar.gz terrascan
sudo install terrascan /usr/local/bin/
# Docker
docker pull tenable/terrascan
Verify:
terrascan version
Init (Download Policies)
terrascan init
→ Download policy bundle ไปที่ ~/.terrascan/
Basic Scan
# Scan current directory
terrascan scan
# Specific path
terrascan scan -d ./terraform
# Specific cloud
terrascan scan -t aws # หรือ azure, gcp, k8s, github
terrascan scan -t aws,azure
ตัวอย่าง Output
Violation Details
Description : S3 buckets should have all access logged
File : main.tf
Module Name : root
Plan Root : ./
Line : 5
Severity : HIGH
Rule Name : s3EnforceUserAcl
Rule ID : AC_AWS_0207
Resource Name : data
Resource Type : aws_s3_bucket
Category : Identity and Access Management
------------------------------
Scan Summary
File/Folder : ./
IaC Type : terraform
Scanned At : 2026-05-07 10:00:00 UTC
Policies Validated : 590
Violated Policies : 5
Low : 1
Medium : 2
High : 2
Critical : 0
Output Formats
# JSON
terrascan scan -o json
# YAML
terrascan scan -o yaml
# SARIF (GitHub)
terrascan scan -o sarif
# JUnit XML (CI)
terrascan scan -o junit-xml
# Human-readable (default)
terrascan scan -o human
Severity Filter
terrascan scan --severity high
terrascan scan --severity critical
Specific Policies
# Run specific policy
terrascan scan --policy-type aws --rule AC_AWS_0207
# Skip policies
terrascan scan --skip-rules "AC_AWS_0001,AC_AWS_0002"
Compliance Standards
Terrascan supports:
- CIS AWS/Azure/GCP/Kubernetes
- GDPR
- HIPAA
- ISO 27001
- NIST
- PCI DSS
- SOC 2
terrascan scan -t aws --policy-type aws --categories "CIS"
Inline Skip
#ts:skip=AC_AWS_0001 reason for skipping
resource "aws_s3_bucket" "test" {
bucket = "test"
}
Config File
terrascan.yaml
policies:
- --policy-type aws
severity:
- high
- critical
skip-rules:
- AC_AWS_0001
categories:
- "Identity and Access Management"
- "Encryption and Key Management"
show-passed: false
terrascan scan -c terrascan.yaml
Custom Policies (Rego)
policies/aws/no-public-s3.rego
package accurics
publicS3[resource_id] {
bucket := input.aws_s3_bucket[name]
bucket.config.acl == "public-read"
resource_id := bucket.id
}
policies/aws/no-public-s3.json
{
"name": "no-public-s3",
"file": "no-public-s3.rego",
"policy_type": "aws",
"resource_type": "aws_s3_bucket",
"template_args": null,
"severity": "HIGH",
"description": "S3 bucket has public ACL",
"reference_id": "CUSTOM-001",
"category": "Identity and Access Management",
"version": 1
}
terrascan scan --policy-path ./policies
CI/CD Integration
GitHub Actions
.github/workflows/terrascan.yml
on: pull_request
jobs:
terrascan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Terrascan
uses: tenable/terrascan-action@main
with:
iac_type: terraform
iac_version: v15
policy_type: aws
only_warn: false
sarif_upload: true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: terrascan.sarif
GitLab CI
.gitlab-ci.yml
terrascan:
image: tenable/terrascan:latest
script:
- terrascan scan -d . --severity high
Docker
docker run --rm -v $(pwd):/iac -w /iac tenable/terrascan:latest \
scan -d . -o sarif > terrascan.sarif
Pre-commit Hook
.pre-commit-config.yaml
- repo: https://github.com/tenable/terrascan
rev: v1.19.0
hooks:
- id: terraform-pre-commit
args:
- --severity=high
Server Mode
# Run as server
terrascan server --port 9010
# Scan via API
curl -X POST http://localhost:9010/v1/terraform/v15/aws/local/dir/scan \
-F "[email protected]"
→ Useful for IDE integration / custom workflows
ตัวอย่าง: Scan with Multi-Cloud
terrascan scan \
-t aws,azure,gcp \
--severity high \
-o sarif \
> scan-results.sarif
Compare Tools
| Feature | Terrascan | KICS | Checkov | Trivy |
|---|---|---|---|---|
| Policies | 500+ | 2,400+ | 750+ | 1,000+ |
| Compliance Standards | ✅ Built-in (CIS, HIPAA, etc.) | Some | Yes | Some |
| Multi-cloud | ✅ | ✅ | ✅ | ✅ |
| Custom (Rego) | ✅ | ✅ | Python | ✅ |
| Speed | Medium | Medium | Slow | Fast |
| Server Mode | ✅ | ❌ | ❌ | ❌ |
→ Terrascan = strong on compliance standards
Best Practices
✅ DO:
- Run Terrascan ใน PR + main
- ใช้ compliance categories (CIS, HIPAA) ตามอุตสาหกรรม
- Filter severity HIGH,CRITICAL
- Skip false positives ผ่าน config
- Update policy bundle regularly (terrascan init)
❌ DON'T:
- ห้าม run all 500+ policies ถ้าไม่ relevant
- ห้าม ignore HIGH โดยไม่อ่าน
- ห้าม skip terrascan init (no policies = no scan)
ตัวอย่าง Real Output (HIPAA Compliance)
terrascan scan -t aws --categories "HIPAA"
Violation: S3 bucket without encryption
Severity: CRITICAL
Compliance: HIPAA Section 164.312(a)(2)(iv)
Violation: RDS without encryption at rest
Severity: HIGH
Compliance: HIPAA Section 164.312(e)(1)
Violation: CloudTrail not enabled
Severity: HIGH
Compliance: HIPAA Section 164.312(b)
Limitations
- Less queries than KICS / Checkov
- ไม่รองรับ CloudFormation, Ansible
- บาง edge case ของ Terraform 1.x ยังไม่ optimal
สรุป
- Terrascan = static analyzer สำหรับ IaC โดย Tenable
- 500+ policies, มี compliance standards built-in (CIS, HIPAA, GDPR, PCI)
- รองรับ Terraform, K8s, Helm, Kustomize, Dockerfile
- Custom policies ผ่าน Rego (เหมือน OPA, KICS)
- Server mode + REST API
- ใช้คู่กับ KICS/Checkov ครอบคลุมที่สุด
ต่อไป → Checkov