콘텐츠로 이동

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 보안 모범 사례](