TFSec 치트 시트
## 개요
TFSec은 배포 전 Infrastructure as Code의 잠재적인 보안 문제를 식별하는 Terraform 코드용 정적 분석 보안 스캐너입니다. 이 도구는 여러 클라우드 제공업체에 걸쳐 포괄적인 보안 검사를 제공하며, 자세한 수정 지침을 제공하고 CI/CD 파이프라인에 원활하게 통합됩니다.
⚠️ 참고: 무료 및 오픈 소스 도구. 2023년 현재 Trivy의 일부입니다.
Would you like me to continue with the rest of the translations? I can proceed section by section if you confirm.```bash
Linux/macOS
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash
macOS with Homebrew
brew install tfsec
Windows with Chocolatey
choco install tfsec
Windows with Scoop
scoop install tfsec
Direct download
Visit: https://github.com/aquasecurity/tfsec/releases
Download appropriate binary for your platform
### Docker Installation
```bash
# Pull Docker image
docker pull aquasec/tfsec:latest
# Run with Docker
docker run --rm -it \
-v $(pwd):/src \
aquasec/tfsec:latest /src
# Docker alias for convenience
alias tfsec='docker run --rm -it -v $(pwd):/src aquasec/tfsec:latest'
Package Managers
# Alpine Linux
apk add tfsec
# Arch Linux
yay -S tfsec
# Ubuntu/Debian (via snap)
sudo snap install tfsec
# Go install
go install github.com/aquasecurity/tfsec/cmd/tfsec@latest
Basic Usage
Simple Scan
# Scan current directory
tfsec
# Scan specific directory
tfsec /path/to/terraform/code
# Scan with verbose output
tfsec --verbose
# Scan and show passed checks
tfsec --include-passed
Output Formats
# JSON output
tfsec --format json
# SARIF output
tfsec --format sarif
# JUnit XML output
tfsec --format junit
# CSV output
tfsec --format csv
# Checkstyle XML output
tfsec --format checkstyle
# GitHub output
tfsec --format github
# Save output to file
tfsec --format json --out results.json
Filtering Results
# Show only high severity issues
tfsec --minimum-severity HIGH
# Show critical and high severity
tfsec --minimum-severity CRITICAL
# Include specific checks
tfsec --include-checks AWS001,AWS002
# Exclude specific checks
tfsec --exclude-checks AWS001,AWS002
# Exclude by severity
tfsec --exclude-severity LOW,MEDIUM
Configuration
Configuration File
# .tfsec.yml or tfsec.yml
severity_overrides:
AWS001: ERROR
AWS002: WARNING
exclude_checks:
- AWS001
- AWS002
include_checks:
- AWS003
- AWS004
minimum_severity: MEDIUM
exclude_paths:
- "**/.terraform/**"
- "**/node_modules/**"
- "examples/**"
include_paths:
- "modules/**"
- "environments/**"
Environment Variables
# Set configuration via environment variables
export TFSEC_MINIMUM_SEVERITY=HIGH
export TFSEC_EXCLUDE_CHECKS=AWS001,AWS002
export TFSEC_FORMAT=json
export TFSEC_OUT=results.json
# Run with environment configuration
tfsec
Custom Checks Directory
# Specify custom checks directory
tfsec --custom-check-dir ./custom-checks
# Multiple custom check directories
tfsec --custom-check-dir ./custom-checks --custom-check-dir ./team-checks
Cloud Provider Coverage
AWS Security Checks
# AWS-specific scan
tfsec --include-checks AWS*
# Common AWS security issues:
# - S3 bucket encryption
# - IAM policy issues
# - Security group misconfigurations
# - RDS encryption
# - EBS encryption
# - CloudTrail configuration
# - VPC security
AWS Examples
# ❌ Insecure S3 bucket
resource "aws_s3_bucket" "bad_example" {
bucket = "my-bucket"
# Missing encryption configuration
}
# ✅ Secure S3 bucket
resource "aws_s3_bucket" "good_example" {
bucket = "my-bucket"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
bucket = aws_s3_bucket.good_example.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
# ❌ Overly permissive security group
resource "aws_security_group" "bad_example" {
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# ✅ Restrictive security group
resource "aws_security_group" "good_example" {
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
}
Azure Security Checks
# Azure-specific scan
tfsec --include-checks AZURE*
# Common Azure security issues:
# - Storage account encryption
# - Network security groups
# - Key Vault configuration
# - SQL Database security
# - Virtual machine security
Azure Examples
# ❌ Insecure storage account
resource "azurerm_storage_account" "bad_example" {
name = "storageaccountname"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "GRS"
# Missing encryption configuration
}
# ✅ Secure storage account
resource "azurerm_storage_account" "good_example" {
name = "storageaccountname"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "GRS"
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
encryption {
services {
blob {
enabled = true
}
file {
enabled = true
}
}
source = "Microsoft.Storage"
}
}
Google Cloud Security Checks
# GCP-specific scan
tfsec --include-checks GCP*
# Common GCP security issues:
# - Storage bucket permissions
# - Compute instance security
# - IAM bindings
# - Network security
# - Encryption settings
GCP Examples
# ❌ Public storage bucket
resource "google_storage_bucket" "bad_example" {
name = "my-bucket"
location = "US"
uniform_bucket_level_access = false
}
resource "google_storage_bucket_iam_member" "bad_example" {
bucket = google_storage_bucket.bad_example.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
# ✅ Secure storage bucket
resource "google_storage_bucket" "good_example" {
name = "my-bucket"
location = "US"
uniform_bucket_level_access = true
encryption {
default_kms_key_name = google_kms_crypto_key.example.id
}
}
resource "google_storage_bucket_iam_member" "good_example" {
bucket = google_storage_bucket.good_example.name
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.example.email}"
}
Inline Suppressions
Suppression Comments
# Suppress specific check
resource "aws_s3_bucket" "example" {
#tfsec:ignore:AWS002
bucket = "my-bucket"
# Bucket encryption handled by separate resource
}
# Suppress multiple checks
resource "aws_security_group" "example" {
#tfsec:ignore:AWS007,AWS008
name_prefix = "example"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Suppress with explanation
resource "aws_instance" "example" {
#tfsec:ignore:AWS012:This instance needs public IP for external access
ami = "ami-12345678"
instance_type = "t2.micro"
associate_public_ip_address = true
}
Block-Level Suppressions
# Suppress entire resource block
#tfsec:ignore:*
resource "aws_s3_bucket" "legacy" {
bucket = "legacy-bucket"
# Legacy bucket with known issues
# Will be migrated in next sprint
}
# Suppress specific attribute
resource "aws_db_instance" "example" {
allocated_storage = 20
engine = "mysql"
#tfsec:ignore:AWS017
storage_encrypted = false # Encryption handled at application level
}
Conditional Suppressions
# Suppress based on condition
resource "aws_s3_bucket" "example" {
bucket = var.bucket_name
# Only ignore in development environment
#tfsec:ignore:AWS002:exp:2024-12-31
# Temporary suppression with expiration
}
CI/CD Integration
GitHub Actions
# .github/workflows/tfsec.yml
name: TFSec Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
tfsec:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run TFSec
uses: aquasecurity/tfsec-action@v1.0.3
with:
soft_fail: true
format: sarif
output: tfsec.sarif
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: tfsec.sarif
- name: TFSec Report
uses: aquasecurity/tfsec-pr-commenter-action@v1.3.1
with:
github_token: ${{ github.token }}
GitLab CI
# .gitlab-ci.yml
tfsec:
stage: security
image: aquasec/tfsec:latest
script:
- tfsec --format gitlab-sast --out gl-sast-report.json .
artifacts:
reports:
sast: gl-sast-report.json
paths:
- gl-sast-report.json
expire_in: 1 week
only:
- merge_requests
- main
Jenkins Pipeline
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('TFSec Scan') {
steps {
script {
docker.image('aquasec/tfsec:latest').inside {
sh '''
tfsec --format junit --out tfsec-results.xml .
tfsec --format json --out tfsec-results.json .
'''
}
}
}
post {
always {
publishTestResults testResultsPattern: 'tfsec-results.xml'
archiveArtifacts artifacts: 'tfsec-results.json', fingerprint: true
}
}
}
}
}
Azure DevOps
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Docker@2
displayName: 'Run TFSec Security Scan'
inputs:
command: 'run'
arguments: >
--rm
-v $(Build.SourcesDirectory):/src
aquasec/tfsec:latest
--format junit --out /src/tfsec-results.xml /src
- task: PublishTestResults@2
displayName: 'Publish TFSec Results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'tfsec-results.xml'
testRunTitle: 'TFSec Security Scan'
condition: always()
Custom Checks
Writing Custom Checks
// custom-check.go
package main
import (
"github.com/aquasecurity/tfsec/pkg/provider"
"github.com/aquasecurity/tfsec/pkg/result"
"github.com/aquasecurity/tfsec/pkg/rule"
"github.com/aquasecurity/tfsec/pkg/scanner"
)
func init() {
scanner.RegisterCheckRule(rule.Rule{
Provider: provider.AWSProvider,
Service: "s3",
ShortCode: "custom-bucket-naming",
Summary: "S3 bucket names should follow company naming convention",
Impact: "Non-standard bucket names may cause confusion",
Resolution: "Use company naming convention: company-env-purpose-random",
Explanation: "All S3 buckets should follow the company naming convention",
Links: []string{
"https://company.com/docs/naming-conventions",
},
Terraform: &rule.EngineMetadata{
GoodExamples: []string{`
resource "aws_s3_bucket" "good_example" {
bucket = "mycompany-prod-data-abc123"
}
`},
BadExamples: []string{`
resource "aws_s3_bucket" "bad_example" {
bucket = "my-random-bucket-name"
}
`},
Links: []string{
"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket",
},
RemediationMarkdown: `
Ensure S3 bucket names follow the company naming convention:
- Format: company-environment-purpose-randomstring
- Use lowercase letters and hyphens only
- Keep names descriptive but concise
`,
},
Severity: rule.SeverityMedium,
}, func(s *scanner.Scanner, rule *rule.Rule) (results []result.Result) {
// Custom check logic here
return results
})
}
Custom Check Configuration
# custom-checks.yml
checks:
- id: CUSTOM001
name: "Company S3 Naming Convention"
description: "S3 buckets must follow company naming convention"
severity: MEDIUM
provider: aws
service: s3
resource_type: aws_s3_bucket
attribute: bucket
pattern: "^mycompany-(dev|staging|prod)-[a-z]+-[a-z0-9]{6}$"
message: "Bucket name must follow format: mycompany-{env}-{purpose}-{random}"
Loading Custom Checks
# Load custom checks from directory
tfsec --custom-check-dir ./custom-checks
# Load custom checks from multiple directories
tfsec --custom-check-dir ./custom-checks --custom-check-dir ./team-checks
# Use custom configuration file
tfsec --config-file ./custom-tfsec-config.yml
Advanced Features
Terraform Plan Analysis
# Analyze Terraform plan file
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
tfsec --tfplan tfplan.json
# Analyze plan with specific format
tfsec --tfplan tfplan.json --format json --out plan-results.json
Module Analysis
# Scan Terraform modules
tfsec ./modules/
# Scan specific module
tfsec ./modules/vpc/
# Scan with module path context
tfsec --include-paths "modules/**" --exclude-paths "examples/**"
Workspace Analysis
# Analyze specific Terraform workspace
terraform workspace select production
terraform plan -out=prod-plan
terraform show -json prod-plan > prod-plan.json
tfsec --tfplan prod-plan.json --out prod-security-report.json
Integration with Terraform Cloud
# Download plan from Terraform Cloud
# (requires API token and run ID)
curl -H "Authorization: Bearer $TFC_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
"https://app.terraform.io/api/v2/runs/$RUN_ID/plan" \
| jq -r '.data.attributes.log-read-url' \
| xargs curl -o plan.json
tfsec --tfplan plan.json
Reporting and Metrics
Detailed Reporting
# Generate comprehensive report
tfsec --format json --include-passed --out detailed-report.json
# Generate SARIF report for security tools
tfsec --format sarif --out security-report.sarif
# Generate multiple formats
tfsec --format json --out results.json
tfsec --format html --out report.html
tfsec --format csv --out metrics.csv
Metrics Collection
# Extract metrics from JSON report
jq '.results | group_by(.severity) | map({severity: .[0].severity, count: length})' results.json
# Count issues by provider
jq '.results | group_by(.rule.provider) | map({provider: .[0].rule.provider, count: length})' results.json
# Get top failing checks
jq '.results | group_by(.rule.id) | map({check: .[0].rule.id, count: length}) | sort_by(.count) | reverse | .[0:10]' results.json
Dashboard Integration
# Python script to parse TFSec results
import json
import matplotlib.pyplot as plt
def analyze_tfsec_results(results_file):
with open(results_file, 'r') as f:
data = json.load(f)
# Count by severity
severity_counts = {}
for result in data['results']:
severity = result['severity']
severity_counts[severity] = severity_counts.get(severity, 0) + 1
# Create visualization
plt.figure(figsize=(10, 6))
plt.bar(severity_counts.keys(), severity_counts.values())
plt.title('Security Issues by Severity')
plt.xlabel('Severity')
plt.ylabel('Count')
plt.savefig('tfsec-dashboard.png')
return severity_counts
# Usage
results = analyze_tfsec_results('results.json')
print(f"Security issues found: {results}")
Performance Optimization
Large Codebase Optimization
# Optimize for large codebases
tfsec --concurrency-limit 10 --exclude-paths "**/.terraform/**"
# Scan specific directories only
tfsec ./environments/production/
# Use include patterns for focused scanning
tfsec --include-paths "**/*.tf" --exclude-paths "**/examples/**"
Caching and Incremental Scans
# Cache results for faster subsequent scans
export TFSEC_CACHE_DIR=~/.tfsec-cache
tfsec --cache-dir ~/.tfsec-cache
# Incremental scanning (scan only changed files)
# Get changed files from git
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | grep '\.tf$' | tr '\n' ' ')
if [ -n "$CHANGED_FILES" ]; then
tfsec $CHANGED_FILES
fi
Parallel Processing
# Run multiple TFSec instances in parallel
find . -name "*.tf" -type d | \
xargs -I {} -P 4 tfsec --format json --out {}/tfsec-results.json {}
# Combine results
jq -s 'add' **/tfsec-results.json > combined-results.json
Troubleshooting
Common Issues
# Debug mode for troubleshooting
tfsec --debug
# Verbose output
tfsec --verbose
# Check version and supported providers
tfsec --version
# Validate configuration file
tfsec --config-file tfsec.yml --debug
Memory and Performance Issues
# Increase memory limit for large projects
export GOMAXPROCS=4
export GOGC=100
# Reduce memory usage
tfsec --concurrency-limit 2 --exclude-paths "**/.terraform/**"
# Profile memory usage
tfsec --profile-memory --out memory-profile.prof
False Positives
# Handle false positives with suppressions
# Use inline comments for specific cases
#tfsec:ignore:AWS001:This is a false positive because...
# Update configuration to exclude problematic checks
# .tfsec.yml
exclude_checks:
- AWS001 # False positive in our use case
# Report false positives to TFSec team
# Create issue at: https://github.com/aquasecurity/tfsec/issues
Migration to Trivy
Trivy Integration
# TFSec is now part of Trivy
# Install Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Scan with Trivy (includes TFSec functionality)
trivy config .
# Use TFSec-compatible options
trivy config --format json --output results.json .
```### 마이그레이션 명령어
```bash
# Old TFSec command
tfsec --format json --out results.json
# New Trivy equivalent
trivy config --format json --output results.json .
# Migrate configuration
# .tfsec.yml becomes .trivyignore or trivy.yaml
```## 모범 사례
```bash
# 1. Start with baseline scan
tfsec --format json --out baseline.json
# 2. Implement in CI/CD with soft fail initially
tfsec --soft-fail
# 3. Gradually reduce acceptable risk levels
tfsec --minimum-severity HIGH
# 4. Regular security reviews
tfsec --format html --out weekly-report.html
```### 팀 도입
```bash
# Developer workflow:
# 1. Pre-commit hooks
echo '#!/bin/bash
tfsec --minimum-severity HIGH
' > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# 2. IDE integration
# Install TFSec extension for VS Code or other IDEs
# 3. Regular training
# Schedule security awareness sessions
# Share common vulnerability patterns
# Review security findings in team meetings
```### 구성 관리
```bash
# Version control all configuration
git add .tfsec.yml
git commit -m "Add TFSec security scanning configuration"
# Environment-specific configurations
# .tfsec-dev.yml - Development environment
# .tfsec-prod.yml - Production environment
# Use appropriate config per environment
tfsec --config-file .tfsec-${ENVIRONMENT}.yml
```## 리소스
https://aquasecurity.github.io/tfsec/##
# 문서
- [TFSec 문서](https://github.com/aquasecurity/tfsec)
- [GitHub 저장소](https://aquasecurity.github.io/tfsec/latest/checks/)
- [참조 확인](https://github.com/aquasecurity/tfsec/discussions)
https://slack.aquasec.com/##
# 커뮤니티
- [GitHub 토론](https://stackoverflow.com/questions/tagged/tfsec)
- [Slack 커뮤니티](https://learn.hashicorp.com/tutorials/terraform/security)
- [Stack Overflow](https://www.aquasec.com/cloud-native-academy/)
https://www.aquasec.com/devsecops/##
# 교육
- [Terraform 보안 모범 사례](