Saltar a contenido

Terrascan Cheat Sheet

"Clase de la hoja" id="copy-btn" class="copy-btn" onclick="copyAllCommands()" Copiar todos los comandos id="pdf-btn" class="pdf-btn" onclick="generatePDF()" Generar PDF seleccionado/button ■/div titulada

Sinopsis

Terrascan es un analizador de códigos estáticos para la infraestructura como código (IaC) que ayuda a detectar violaciones de cumplimiento y seguridad en el suministro de infraestructura nativa en la nube. Soporta a múltiples proveedores de IaC incluyendo Terraform, Kubernetes, Helm, Kustomize, Dockerfiles y plantillas de formación de nubes. Terrascan ofrece más de 500 policías y apoya OPA, Rego Language y JSON/YAML para escribir políticas personalizadas.

Características clave: Multi-Ia C support, 500+ built-in policies, custom policy creation, CI/CD integration, compliance frameworks (CIS, NIST, AWS Foundational Security Standard), and comprehensive reporting.

Instalación y configuración

Instalación binaria

# Download latest release for Linux
curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" > terrascan.tar.gz

# Extract and install
tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz
sudo install terrascan /usr/local/bin && rm terrascan

# Verify installation
terrascan version

# Download for macOS
curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Darwin_x86_64.tar.gz")" > terrascan.tar.gz

# Download for Windows
curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Windows_x86_64.zip")" > terrascan.zip

Paquete Manager Instalación

# Homebrew (macOS/Linux)
brew install terrascan

# Chocolatey (Windows)
choco install terrascan

# Scoop (Windows)
scoop install terrascan

# Arch Linux
yay -S terrascan

# Verify installation
terrascan version

Docker Instalación

# Pull Docker image
docker pull tenable/terrascan:latest

# Create alias for easier usage
echo 'alias terrascan="docker run --rm -it -v $(pwd):/iac -w /iac tenable/terrascan"' >> ~/.bashrc
source ~/.bashrc

# Test installation
terrascan version

# Run with volume mount
docker run --rm -it -v $(pwd):/iac -w /iac tenable/terrascan scan

# Create Docker wrapper script
cat > terrascan-docker.sh << 'EOF'
#!/bin/bash
docker run --rm -it \
  -v $(pwd):/iac \
  -w /iac \
  tenable/terrascan "$@"
EOF

chmod +x terrascan-docker.sh
sudo mv terrascan-docker.sh /usr/local/bin/terrascan-docker

Fuente: Instalación

# Install Go (if not already installed)
wget https://golang.org/dl/go1.19.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Clone repository
git clone https://github.com/tenable/terrascan.git
cd terrascan

# Build from source
make build

# Install binary
sudo cp bin/terrascan /usr/local/bin/

# Verify installation
terrascan version

# Build with specific version
git checkout v1.18.0
make build

Configuración y configuración

# Initialize Terrascan configuration
terrascan init

# Create configuration directory
mkdir -p ~/.terrascan

# Create default configuration file
cat > ~/.terrascan/config.toml << 'EOF'
[scan]
  # Scan configuration
  iac-type = ""
  iac-version = ""
  cloud-provider = ["aws", "azure", "gcp", "github"]
  severity = "high"
  confidence = "high"

[rules]
  # Rule configuration
  skip-rules = []
  include-rules = []

[output]
  # Output configuration
  format = "human"
  output-file = ""

[logging]
  # Logging configuration
  level = "info"

[notifications]
  # Notification configuration
  webhook = ""

[policy]
  # Policy configuration
  rego-subdir = ""
  policy-path = []

[server]
  # Server configuration
  port = 9010
  cert-file = ""
  private-key-file = ""
EOF

# Set environment variables
export TERRASCAN_CONFIG=~/.terrascan/config.toml
export TERRASCAN_LOG_LEVEL=info

# Create policy directory
mkdir -p ~/.terrascan/policies

# Download additional policies
git clone https://github.com/tenable/terrascan.git /tmp/terrascan-policies
cp -r /tmp/terrascan-policies/pkg/policies/opa/rego/* ~/.terrascan/policies/

Uso básico y comandos

Escáner simple

# Scan current directory (auto-detect IaC type)
terrascan scan

# Scan specific directory
terrascan scan -d /path/to/iac/files

# Scan specific file
terrascan scan -f main.tf

# Scan with specific IaC type
terrascan scan -t terraform

# Scan with specific cloud provider
terrascan scan -c aws

# Scan with specific IaC version
terrascan scan -i terraform -v v14

Opciones avanzadas de exploración

# Scan with specific severity levels
terrascan scan --severity high
terrascan scan --severity medium,high

# Scan with specific confidence levels
terrascan scan --confidence high

# Scan with custom policy path
terrascan scan --policy-path /path/to/custom/policies

# Scan with rule filtering
terrascan scan --skip-rules AC_AWS_0001,AC_AWS_0002
terrascan scan --include-rules AC_AWS_0001,AC_AWS_0002

# Scan with output formatting
terrascan scan --output json
terrascan scan --output xml
terrascan scan --output yaml
terrascan scan --output junit-xml
terrascan scan --output sarif

# Scan with output file
terrascan scan --output json --output-file results.json

# Scan with verbose output
terrascan scan --verbose

# Scan with configuration file
terrascan scan --config-path ~/.terrascan/config.toml

Escáner de tipo Multi-IaC

# Terraform scanning
terrascan scan -t terraform -d ./terraform/

# Kubernetes scanning
terrascan scan -t k8s -d ./k8s/

# Helm chart scanning
terrascan scan -t helm -d ./helm-charts/

# Kustomize scanning
terrascan scan -t kustomize -d ./kustomize/

# Dockerfile scanning
terrascan scan -t docker -f Dockerfile

# CloudFormation scanning
terrascan scan -t cfn -d ./cloudformation/

# ARM template scanning
terrascan scan -t arm -d ./arm-templates/

# Scan multiple IaC types in one command
find . -name "*.tf" -exec terrascan scan -t terraform -f {} \;
find . -name "*.yaml" -exec terrascan scan -t k8s -f {} \;

Advanced Policy Management

Creación de políticas personalizadas

# Create custom policy directory
mkdir -p ~/.terrascan/custom-policies

# Create custom Rego policy
cat > ~/.terrascan/custom-policies/custom_s3_policy.rego << 'EOF'
package accurics

# Custom S3 bucket policy
s3BucketShouldHaveCustomTags[retVal] {
    resource := input.aws_s3_bucket[_]
    not resource.config.tags.Environment

    retVal := {
        "Id": "CUSTOM_S3_001",
        "RuleID": "CUSTOM_S3_001", 
        "Severity": "HIGH",
        "Description": "S3 bucket should have Environment tag",
        "Category": "S3",
        "ResourceType": "aws_s3_bucket",
        "File": resource.file,
        "LineNumber": resource.line,
        "IssueType": "MissingAttribute",
        "SearchKey": sprintf("aws_s3_bucket[%s].tags", [resource.name]),
        "ExpectedValues": ["Environment tag should be present"],
        "ActualValues": [resource.config.tags],
        "References": ["https://docs.aws.amazon.com/s3/latest/userguide/object-tagging.html"]
    }
}

# Custom EC2 instance policy
ec2InstanceShouldUseApprovedAMIs[retVal] {
    resource := input.aws_instance[_]
    approved_amis := ["ami-12345678", "ami-87654321", "ami-11111111"]
    not resource.config.ami in approved_amis

    retVal := {
        "Id": "CUSTOM_EC2_001",
        "RuleID": "CUSTOM_EC2_001",
        "Severity": "MEDIUM", 
        "Description": "EC2 instance should use approved AMIs only",
        "Category": "EC2",
        "ResourceType": "aws_instance",
        "File": resource.file,
        "LineNumber": resource.line,
        "IssueType": "WrongValue",
        "SearchKey": sprintf("aws_instance[%s].ami", [resource.name]),
        "ExpectedValues": approved_amis,
        "ActualValues": [resource.config.ami],
        "References": ["https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html"]
    }
}
EOF

# Use custom policies
terrascan scan --policy-path ~/.terrascan/custom-policies

# Create JSON-based custom policy
cat > ~/.terrascan/custom-policies/custom_policy.json << 'EOF'
{
  "rules": [
    {
      "id": "CUSTOM_JSON_001",
      "description": "RDS instances should have backup retention period >= 7 days",
      "severity": "HIGH",
      "category": "RDS",
      "resourceType": "aws_db_instance",
      "conditions": {
        "and": [
          {
            "attribute": "backup_retention_period",
            "operator": "lt",
            "value": 7
          }
        ]
      }
    }
  ]
}
EOF

# Validate custom policies
terrascan scan --policy-path ~/.terrascan/custom-policies --verbose

Scripts de gestión de políticas

#!/usr/bin/env python3
# Advanced policy management for Terrascan

import json
import yaml
import os
import subprocess
import argparse
from pathlib import Path

class TerrascanPolicyManager:
    """Advanced policy management for Terrascan"""

    def __init__(self, policy_dir="~/.terrascan/policies"):
        self.policy_dir = Path(policy_dir).expanduser()
        self.policy_dir.mkdir(parents=True, exist_ok=True)

    def create_policy_from_template(self, policy_name, resource_type, severity="HIGH"):
        """Create a new policy from template"""

        template = f'''package accurics

# Custom policy: {policy_name}
{policy_name.lower().replace(" ", "_")}[retVal] {{
    resource := input.{resource_type}[_]

    # Add your policy logic here
    condition := true  # Replace with actual condition
    condition

    retVal := {{
        "Id": "CUSTOM_{resource_type.upper()}_001",
        "RuleID": "CUSTOM_{resource_type.upper()}_001",
        "Severity": "{severity}",
        "Description": "{policy_name}",
        "Category": "{resource_type.split('_')[1].upper()}",
        "ResourceType": "{resource_type}",
        "File": resource.file,
        "LineNumber": resource.line,
        "IssueType": "MissingAttribute",
        "SearchKey": sprintf("{resource_type}[%s]", [resource.name]),
        "ExpectedValues": ["Expected value"],
        "ActualValues": ["Actual value"],
        "References": ["https://example.com/reference"]
    }}
}}
'''

        policy_file = self.policy_dir / f"{policy_name.lower().replace(' ', '_')}.rego"
        with open(policy_file, 'w') as f:
            f.write(template)

        print(f"Policy created: {policy_file}")
        return policy_file

    def validate_policies(self):
        """Validate all policies in the policy directory"""

        print("Validating policies...")

        for policy_file in self.policy_dir.glob("*.rego"):
            try:
                # Use opa fmt to validate syntax
                result = subprocess.run(
                    ["opa", "fmt", str(policy_file)],
                    capture_output=True,
                    text=True
                )

                if result.returncode == 0:
                    print(f"✅ {policy_file.name}: Valid")
                else:
                    print(f"❌ {policy_file.name}: Invalid - {result.stderr}")

            except FileNotFoundError:
                print("⚠️  OPA not found. Install OPA to validate Rego policies.")
                break

    def list_policies(self):
        """List all available policies"""

        print("Available policies:")
        print("-" * 50)

        for policy_file in self.policy_dir.glob("*.rego"):
            with open(policy_file, 'r') as f:
                content = f.read()

            # Extract policy description
            lines = content.split('\n')
            description = "No description"

            for line in lines:
                if "Description" in line and '"' in line:
                    description = line.split('"')[1]
                    break

            print(f"📄 {policy_file.name}")
            print(f"   Description: {description}")
            print()

    def test_policy(self, policy_file, test_data_file):
        """Test a policy against test data"""

        try:
            # Run terrascan with the specific policy
            result = subprocess.run([
                "terrascan", "scan",
                "--policy-path", str(self.policy_dir),
                "-f", test_data_file,
                "--output", "json"
            ], capture_output=True, text=True)

            if result.returncode == 0:
                output = json.loads(result.stdout)
                violations = output.get("results", {}).get("violations", [])

                print(f"Policy test results for {policy_file}:")
                print(f"Violations found: {len(violations)}")

                for violation in violations:
                    print(f"- {violation.get('rule_name', 'Unknown')}: {violation.get('description', 'No description')}")
            else:
                print(f"Error testing policy: {result.stderr}")

        except Exception as e:
            print(f"Error testing policy: {e}")

    def generate_policy_report(self):
        """Generate a comprehensive policy report"""

        report = {
            "policy_summary": {
                "total_policies": 0,
                "custom_policies": 0,
                "policy_categories": {}
            },
            "policies": []
        }

        for policy_file in self.policy_dir.glob("*.rego"):
            with open(policy_file, 'r') as f:
                content = f.read()

            # Parse policy information
            policy_info = {
                "file": policy_file.name,
                "path": str(policy_file),
                "size": policy_file.stat().st_size,
                "rules": []
            }

            # Extract rules from content
            lines = content.split('\n')
            current_rule = None

            for line in lines:
                if '[retVal]' in line:
                    rule_name = line.split('[')[0].strip()
                    current_rule = {"name": rule_name}
                elif current_rule and '"Id"' in line:
                    rule_id = line.split('"')[3]
                    current_rule["id"] = rule_id
                elif current_rule and '"Severity"' in line:
                    severity = line.split('"')[3]
                    current_rule["severity"] = severity
                elif current_rule and '"Category"' in line:
                    category = line.split('"')[3]
                    current_rule["category"] = category
                    policy_info["rules"].append(current_rule)

                    # Update category count
                    if category in report["policy_summary"]["policy_categories"]:
                        report["policy_summary"]["policy_categories"][category] += 1
                    else:
                        report["policy_summary"]["policy_categories"][category] = 1

                    current_rule = None

            report["policies"].append(policy_info)
            report["policy_summary"]["total_policies"] += 1

            if "custom" in policy_file.name.lower():
                report["policy_summary"]["custom_policies"] += 1

        # Save report
        report_file = self.policy_dir / "policy_report.json"
        with open(report_file, 'w') as f:
            json.dump(report, f, indent=2)

        print(f"Policy report generated: {report_file}")
        return report

def main():
    parser = argparse.ArgumentParser(description='Terrascan Policy Manager')
    parser.add_argument('action', choices=['create', 'validate', 'list', 'test', 'report'])
    parser.add_argument('--name', help='Policy name for creation')
    parser.add_argument('--resource-type', help='Resource type for policy')
    parser.add_argument('--severity', default='HIGH', help='Policy severity')
    parser.add_argument('--policy-file', help='Policy file for testing')
    parser.add_argument('--test-data', help='Test data file')

    args = parser.parse_args()

    manager = TerrascanPolicyManager()

    if args.action == 'create':
        if not args.name or not args.resource_type:
            print("Error: --name and --resource-type required for create action")
            return
        manager.create_policy_from_template(args.name, args.resource_type, args.severity)

    elif args.action == 'validate':
        manager.validate_policies()

    elif args.action == 'list':
        manager.list_policies()

    elif args.action == 'test':
        if not args.policy_file or not args.test_data:
            print("Error: --policy-file and --test-data required for test action")
            return
        manager.test_policy(args.policy_file, args.test_data)

    elif args.action == 'report':
        manager.generate_policy_report()

if __name__ == "__main__":
    main()

CI/CD Integration

GitHub Actions Integration

# .github/workflows/terrascan.yml
name: Terrascan IaC Security Scan

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  terrascan:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Setup Terrascan
      uses: tenable/terrascan-action@main
      with:
        iac_type: terraform
        iac_version: v14
        policy_type: aws
        only_warn: true
        sarif_upload: true

    - name: Run Terrascan Scan
      run: |
        terrascan scan \
          --iac-type terraform \
          --cloud-provider aws,azure,gcp \
          --severity high,medium \
          --output sarif \
          --output-file terrascan-results.sarif

    - name: Upload SARIF file
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: terrascan-results.sarif

    - name: Generate detailed report
      run: |
        terrascan scan \
          --iac-type terraform \
          --output json \
          --output-file terrascan-detailed.json

    - name: Upload scan results
      uses: actions/upload-artifact@v3
      with:
        name: terrascan-results
        path: |
          terrascan-results.sarif
          terrascan-detailed.json

  terrascan-multiple-iac:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        iac_type: [terraform, k8s, helm, dockerfile]

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Install Terrascan
      run: |
        curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" > terrascan.tar.gz
        tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz
        sudo install terrascan /usr/local/bin && rm terrascan

    - name: Scan ${{ matrix.iac_type }}
      run: |
        if [ -d "./${{ matrix.iac_type }}" ]; then
          terrascan scan \
            --iac-type ${{ matrix.iac_type }} \
            --directory ./${{ matrix.iac_type }} \
            --output json \
            --output-file ${{ matrix.iac_type }}-results.json
        fi

    - name: Upload results
      uses: actions/upload-artifact@v3
      if: always()
      with:
        name: ${{ matrix.iac_type }}-scan-results
        path: ${{ matrix.iac_type }}-results.json

GitLab CI Integration

# .gitlab-ci.yml
stages:
  - security-scan
  - report

variables:
  TERRASCAN_VERSION: "latest"

terrascan-scan:
  stage: security-scan
  image: tenable/terrascan:${TERRASCAN_VERSION}

  script:
    - |
      # Scan Terraform files
      if [ -d "./terraform" ]; then
        terrascan scan \
          --iac-type terraform \
          --directory ./terraform \
          --output json \
          --output-file terraform-scan.json
      fi

      # Scan Kubernetes files
      if [ -d "./k8s" ]; then
        terrascan scan \
          --iac-type k8s \
          --directory ./k8s \
          --output json \
          --output-file k8s-scan.json
      fi

      # Scan Helm charts
      if [ -d "./helm" ]; then
        terrascan scan \
          --iac-type helm \
          --directory ./helm \
          --output json \
          --output-file helm-scan.json
      fi

      # Generate combined report
      python3 -c "
import json
import glob

results = []
for file in glob.glob('*-scan.json'):
    with open(file, 'r') as f:
        data = json.load(f)
        results.append({
            'file': file,
            'violations': data.get('results', {}).get('violations', [])
        })

with open('combined-results.json', 'w') as f:
    json.dump(results, f, indent=2)
"

  artifacts:
    reports:
      junit: "*-scan.json"
    paths:
      - "*-scan.json"
      - "combined-results.json"
    expire_in: 1 week

  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

terrascan-report:
  stage: report
  image: python:3.9-slim

  dependencies:
    - terrascan-scan

  script:
    - |
      pip install jinja2

      # Generate HTML report
      python3 << 'EOF'
import json
import jinja2
from datetime import datetime

# Load results
with open('combined-results.json', 'r') as f:
    results = json.load(f)

# Calculate statistics
total_violations = sum(len(r['violations']) for r in results)
high_severity = sum(1 for r in results for v in r['violations'] if v.get('severity') == 'HIGH')
medium_severity = sum(1 for r in results for v in r['violations'] if v.get('severity') == 'MEDIUM')

# HTML template
template = jinja2.Template('''
<!DOCTYPE html>
<html>
<head>
    <title>Terrascan Security Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .header { background: #f4f4f4; padding: 20px; border-radius: 5px; }
        .stats { display: flex; gap: 20px; margin: 20px 0; }
        .stat { background: #e9e9e9; padding: 15px; border-radius: 5px; text-align: center; }
        .violation { border: 1px solid #ddd; margin: 10px 0; padding: 15px; border-radius: 5px; }
        .high { border-left: 5px solid #d32f2f; }
        .medium { border-left: 5px solid #f57c00; }
        .low { border-left: 5px solid #388e3c; }
    </style>
</head>
<body>
    <div class="header">
        <h1>Terrascan Security Report</h1>
        <p>Generated on: {{ timestamp }}</p>
    </div>

    <div class="stats">
        <div class="stat">
            <h3>{{ total_violations }}</h3>
            <p>Total Violations</p>
        </div>
        <div class="stat">
            <h3>{{ high_severity }}</h3>
            <p>High Severity</p>
        </div>
        <div class="stat">
            <h3>{{ medium_severity }}</h3>
            <p>Medium Severity</p>
        </div>
    </div>

    {% for result in results %}
    <h2>{{ result.file }}</h2>
    {% for violation in result.violations %}
    <div class="violation {{ violation.severity.lower() }}">
        <h4>{{ violation.rule_name }}</h4>
        <p><strong>Severity: </strong> {{ violation.severity }}</p>
        <p><strong>Description: </strong> {{ violation.description }}</p>
        <p><strong>File: </strong> {{ violation.file }}:{{ violation.line }}</p>
        <p><strong>Resource: </strong> {{ violation.resource_name }}</p>
    </div>
    {% endfor %}
    {% endfor %}
</body>
</html>
''')

# Render report
html_content = template.render(
    results=results,
    total_violations=total_violations,
    high_severity=high_severity,
    medium_severity=medium_severity,
    timestamp=datetime.now().strftime('%Y-%m-%d %H: %M:%S')
)

with open('terrascan-report.html', 'w') as f:
    f.write(html_content)

print("HTML report generated: terrascan-report.html")
EOF

  artifacts:
    paths:
      - "terrascan-report.html"
    expire_in: 1 month

Jenkins Pipeline Integration

// Jenkinsfile
pipeline {
    agent any

    environment {
        TERRASCAN_VERSION = 'latest'
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Terrascan') {
            steps {
                script {
                    sh '''
                        # Download and install Terrascan
                        curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" > terrascan.tar.gz
                        tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz
                        chmod +x terrascan
                        sudo mv terrascan /usr/local/bin/

                        # Verify installation
                        terrascan version
                    '''
                }
            }
        }

        stage('Terrascan Security Scan') {
            parallel {
                stage('Terraform Scan') {
                    when {
                        expression { fileExists('terraform/') }
                    }
                    steps {
                        script {
                            sh '''
                                terrascan scan \
                                    --iac-type terraform \
                                    --directory ./terraform \
                                    --output json \
                                    --output-file terraform-results.json \
                                    --severity high,medium
                            '''
                        }
                    }
                }

                stage('Kubernetes Scan') {
                    when {
                        expression { fileExists('k8s/') }
                    }
                    steps {
                        script {
                            sh '''
                                terrascan scan \
                                    --iac-type k8s \
                                    --directory ./k8s \
                                    --output json \
                                    --output-file k8s-results.json \
                                    --severity high,medium
                            '''
                        }
                    }
                }

                stage('Dockerfile Scan') {
                    when {
                        expression { fileExists('Dockerfile') }
                    }
                    steps {
                        script {
                            sh '''
                                terrascan scan \
                                    --iac-type docker \
                                    --file ./Dockerfile \
                                    --output json \
                                    --output-file dockerfile-results.json \
                                    --severity high,medium
                            '''
                        }
                    }
                }
            }
        }

        stage('Process Results') {
            steps {
                script {
                    // Process scan results
                    sh '''
                        python3 << 'EOF'
import json
import glob
import os

# Combine all results
all_results = []
total_violations = 0
high_violations = 0
medium_violations = 0

for result_file in glob.glob('*-results.json'):
    if os.path.getsize(result_file) > 0:
        with open(result_file, 'r') as f:
            try:
                data = json.load(f)
                violations = data.get('results', {}).get('violations', [])
                all_results.extend(violations)
                total_violations += len(violations)

                for violation in violations:
                    if violation.get('severity') == 'HIGH':
                        high_violations += 1
                    elif violation.get('severity') == 'MEDIUM':
                        medium_violations += 1

            except json.JSONDecodeError:
                print(f"Error parsing {result_file}")

# Create summary
summary = {
    'total_violations': total_violations,
    'high_violations': high_violations,
    'medium_violations': medium_violations,
    'violations': all_results
}

with open('terrascan-summary.json', 'w') as f:
    json.dump(summary, f, indent=2)

print(f"Total violations: {total_violations}")
print(f"High severity: {high_violations}")
print(f"Medium severity: {medium_violations}")

# Set build status based on violations
if high_violations > 0:
    print("FAILURE: High severity violations found")
    exit(1)
elif medium_violations > 10:  # Threshold for medium violations
    print("UNSTABLE: Too many medium severity violations")
    exit(2)
else:
    print("SUCCESS: No critical violations found")
EOF
                    '''
                }
            }
        }
    }

    post {
        always {
            // Archive results
            archiveArtifacts artifacts: '*-results.json, terrascan-summary.json', 
                           allowEmptyArchive: true

            // Publish results
            publishHTML([
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: '.',
                reportFiles: 'terrascan-summary.json',
                reportName: 'Terrascan Security Report'
            ])
        }

        failure {
            // Send notification on failure
            emailext (
                subject: "Terrascan Security Scan Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "High severity security violations found in IaC. Check the build logs for details.",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }

        unstable {
            // Send notification on unstable build
            emailext (
                subject: "Terrascan Security Scan Unstable: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "Medium severity security violations found in IaC. Review recommended.",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }
    }
}

Configuración y automatización avanzadas

Gestión integral de configuración

#!/bin/bash
# Advanced Terrascan configuration management

setup_terrascan_environment() {
    echo "Setting up Terrascan environment..."

    # Create directory structure
    mkdir -p ~/.terrascan/{config,policies,reports,cache}

    # Create advanced configuration
    cat > ~/.terrascan/config.toml << 'EOF'
[scan]
  # Scan configuration
  iac-type = ""
  iac-version = ""
  cloud-provider = ["aws", "azure", "gcp", "github", "kubernetes"]
  severity = "high"
  confidence = "high"
  timeout = "300s"

[rules]
  # Rule configuration
  skip-rules = []
  include-rules = []

[output]
  # Output configuration
  format = "human"
  output-file = ""

[logging]
  # Logging configuration
  level = "info"
  file = "~/.terrascan/terrascan.log"

[notifications]
  # Notification configuration
  webhook = ""
  slack-webhook = ""
  email-smtp = ""

[policy]
  # Policy configuration
  rego-subdir = ""
  policy-path = ["~/.terrascan/policies"]

[server]
  # Server configuration
  port = 9010
  cert-file = ""
  private-key-file = ""

[cache]
  # Cache configuration
  enabled = true
  directory = "~/.terrascan/cache"
  ttl = "24h"

[integrations]
  # Integration configuration
  jira-url = ""
  jira-username = ""
  jira-token = ""

  github-token = ""
  gitlab-token = ""

  sonarqube-url = ""
  sonarqube-token = ""
EOF

    # Set environment variables
    cat >> ~/.bashrc << 'EOF'
# Terrascan environment variables
export TERRASCAN_CONFIG=~/.terrascan/config.toml
export TERRASCAN_LOG_LEVEL=info
export TERRASCAN_CACHE_DIR=~/.terrascan/cache
export TERRASCAN_POLICY_PATH=~/.terrascan/policies
EOF

    source ~/.bashrc

    echo "Terrascan environment setup complete"
}

# Advanced scanning function
advanced_terrascan_scan() {
    local scan_dir="${1:-.}"
    local output_dir="${2:-./terrascan-results}"
    local config_file="${3:-~/.terrascan/config.toml}"

    echo "Starting advanced Terrascan scan..."
    echo "Scan directory: $scan_dir"
    echo "Output directory: $output_dir"

    # Create output directory
    mkdir -p "$output_dir"

    # Detect IaC types in directory
    iac_types=()

| if find "$scan_dir" -name "*.tf" -type f | head -1 | grep -q .; then |
        iac_types+=("terraform")
    fi

| if find "$scan_dir" -name "*.yaml" -o -name "*.yml" | xargs grep -l "apiVersion\ | kind" 2>/dev/null | head -1 | grep -q .; then |
        iac_types+=("k8s")
    fi

| if find "$scan_dir" -name "Chart.yaml" -type f | head -1 | grep -q .; then |
        iac_types+=("helm")
    fi

| if find "$scan_dir" -name "Dockerfile*" -type f | head -1 | grep -q .; then |
        iac_types+=("docker")
    fi

| if find "$scan_dir" -name "*.json" | xargs grep -l "AWSTemplateFormatVersion\ | Resources" 2>/dev/null | head -1 | grep -q .; then |
        iac_types+=("cfn")
    fi

    echo "Detected IaC types: ${iac_types[*]}"

    # Scan each IaC type
    for iac_type in "${iac_types[@]}"; do
        echo "Scanning $iac_type files..."

        # Multiple output formats
        terrascan scan \
            --iac-type "$iac_type" \
            --directory "$scan_dir" \
            --config-path "$config_file" \
            --output json \
            --output-file "$output_dir/${iac_type}-results.json" \
            --severity high,medium,low

        terrascan scan \
            --iac-type "$iac_type" \
            --directory "$scan_dir" \
            --config-path "$config_file" \
            --output sarif \
            --output-file "$output_dir/${iac_type}-results.sarif"

        terrascan scan \
            --iac-type "$iac_type" \
            --directory "$scan_dir" \
            --config-path "$config_file" \
            --output junit-xml \
            --output-file "$output_dir/${iac_type}-results.xml"
    done

    # Generate combined report
    python3 << EOF
import json
import glob
import os
from datetime import datetime

output_dir = "$output_dir"
results_files = glob.glob(f"{output_dir}/*-results.json")

combined_results = {
    "scan_info": {
        "timestamp": datetime.now().isoformat(),
        "scan_directory": "$scan_dir",
        "iac_types": ${iac_types[@]@Q},
        "total_files_scanned": 0,
        "total_violations": 0
    },
    "results_by_type": {},
    "summary": {
        "high_severity": 0,
        "medium_severity": 0,
        "low_severity": 0,
        "categories": {}
    }
}

for results_file in results_files:
    iac_type = os.path.basename(results_file).replace("-results.json", "")

    try:
        with open(results_file, 'r') as f:
            data = json.load(f)

        violations = data.get("results", {}).get("violations", [])
        combined_results["results_by_type"][iac_type] = {
            "violations": violations,
            "count": len(violations)
        }

        combined_results["scan_info"]["total_violations"] += len(violations)

        # Count by severity
        for violation in violations:
            severity = violation.get("severity", "").lower()
            if severity == "high":
                combined_results["summary"]["high_severity"] += 1
            elif severity == "medium":
                combined_results["summary"]["medium_severity"] += 1
            elif severity == "low":
                combined_results["summary"]["low_severity"] += 1

            # Count by category
            category = violation.get("category", "Unknown")
            if category in combined_results["summary"]["categories"]:
                combined_results["summary"]["categories"][category] += 1
            else:
                combined_results["summary"]["categories"][category] = 1

    except Exception as e:
        print(f"Error processing {results_file}: {e}")

# Save combined results
with open(f"{output_dir}/combined-results.json", 'w') as f:
    json.dump(combined_results, f, indent=2)

print(f"Combined results saved to {output_dir}/combined-results.json")
print(f"Total violations: {combined_results['scan_info']['total_violations']}")
print(f"High severity: {combined_results['summary']['high_severity']}")
print(f"Medium severity: {combined_results['summary']['medium_severity']}")
print(f"Low severity: {combined_results['summary']['low_severity']}")
EOF

    echo "Advanced scan completed. Results saved to: $output_dir"
}

# Automated remediation suggestions
generate_remediation_report() {
    local results_file="$1"
    local output_file="${2:-remediation-report.md}"

    echo "Generating remediation report..."

    python3 << EOF
import json
import re
from datetime import datetime

# Load results
with open("$results_file", 'r') as f:
    data = json.load(f)

violations = data.get("results", {}).get("violations", [])

# Group violations by category and severity
categories = {}
for violation in violations:
    category = violation.get("category", "Unknown")
    severity = violation.get("severity", "Unknown")

    if category not in categories:
        categories[category] = {"HIGH": [], "MEDIUM": [], "LOW": []}

    categories[category][severity].append(violation)

# Generate markdown report
report = f"""# Terrascan Remediation Report

**Generated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
**Total Violations:** {len(violations)}

## Executive Summary

"""

# Add summary statistics
high_count = sum(len(cats["HIGH"]) for cats in categories.values())
medium_count = sum(len(cats["MEDIUM"]) for cats in categories.values())
low_count = sum(len(cats["LOW"]) for cats in categories.values())

report += f"""
|  | Severity | Count | Percentage |  |
| --- | --- | --- |
|  | High | {high_count} | {high_count/len(violations)*100:.1f}% |  |
|  | Medium | {medium_count} | {medium_count/len(violations)*100:.1f}% |  |
|  | Low | {low_count} | {low_count/len(violations)*100:.1f}% |  |

## Remediation Recommendations

"""

# Add remediation suggestions by category
remediation_suggestions = {
    "S3": {
        "description": "Amazon S3 security configurations",
        "common_fixes": [
            "Enable S3 bucket encryption",
            "Configure proper bucket policies",
            "Enable access logging",
            "Block public access"
        ]
    },
    "EC2": {
        "description": "Amazon EC2 security configurations", 
        "common_fixes": [
            "Use security groups instead of 0.0.0.0/0",
            "Enable detailed monitoring",
            "Use IMDSv2 for metadata service",
            "Encrypt EBS volumes"
        ]
    },
    "IAM": {
        "description": "Identity and Access Management",
        "common_fixes": [
            "Follow principle of least privilege",
            "Avoid wildcard permissions",
            "Use managed policies when possible",
            "Enable MFA for sensitive operations"
        ]
    },
    "RDS": {
        "description": "Amazon RDS security configurations",
        "common_fixes": [
            "Enable encryption at rest",
            "Configure backup retention",
            "Use VPC security groups",
            "Enable automated backups"
        ]
    }
}

for category, violations_by_severity in categories.items():
    total_category_violations = sum(len(v) for v in violations_by_severity.values())

    report += f"""
### {category} ({total_category_violations} violations)

"""

    if category in remediation_suggestions:
        report += f"{remediation_suggestions[category]['description']}\\n\\n"
        report += "**Common Fixes:**\\n"
        for fix in remediation_suggestions[category]['common_fixes']:
            report += f"- {fix}\\n"
        report += "\\n"

    # Add specific violations
    for severity in ["HIGH", "MEDIUM", "LOW"]:
        if violations_by_severity[severity]:
            report += f"#### {severity} Severity ({len(violations_by_severity[severity])} violations)\\n\\n"

            for violation in violations_by_severity[severity][:5]:  # Limit to first 5
                report += f"""
**Rule:** {violation.get('rule_name', 'Unknown')}
**Description:** {violation.get('description', 'No description')}
**File:** {violation.get('file', 'Unknown')}:{violation.get('line', 'Unknown')}
**Resource:** {violation.get('resource_name', 'Unknown')}

"""

            if len(violations_by_severity[severity]) > 5:
                report += f"... and {len(violations_by_severity[severity]) - 5} more violations\\n\\n"

# Add next steps
report += """
## Next Steps

1. **Prioritize High Severity Issues:** Address all high severity violations first
2. **Review Medium Severity Issues:** Evaluate business impact and fix accordingly  
3. **Implement Policy as Code:** Use custom Terrascan policies to prevent future violations
4. **Automate Scanning:** Integrate Terrascan into CI/CD pipelines
5. **Regular Reviews:** Schedule periodic security reviews and scans

## Resources

- [Terrascan Documentation](https://runterrascan.io/)
- [AWS Security Best Practices](https://aws.amazon.com/security/security-resources/)
- [Azure Security Documentation](https://docs.microsoft.com/en-us/azure/security/)
- [GCP Security Best Practices](https://cloud.google.com/security/best-practices)
"""

# Save report
with open("$output_file", 'w') as f:
    f.write(report)

print(f"Remediation report generated: $output_file")
EOF
}

# Run setup
setup_terrascan_environment

# Example usage
# advanced_terrascan_scan ./infrastructure ./scan-results
# generate_remediation_report ./scan-results/combined-results.json

Optimización del rendimiento y solución de problemas

Performance Tuning

#!/bin/bash
# Terrascan performance optimization

optimize_terrascan_performance() {
    echo "Optimizing Terrascan performance..."

    # 1. System-level optimizations
    echo "Applying system optimizations..."

    # Increase file descriptor limits
    ulimit -n 65536
    echo "* soft nofile 65536" | sudo tee -a /etc/security/limits.conf
    echo "* hard nofile 65536" | sudo tee -a /etc/security/limits.conf

    # Optimize memory settings
    echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p

    # 2. Terrascan-specific optimizations
    echo "Configuring Terrascan optimizations..."

    # Create optimized configuration
    cat > ~/.terrascan/performance-config.toml << 'EOF'
# High-performance Terrascan configuration
[scan]
  timeout = "600s"           # Increase timeout for large scans

[cache]
  enabled = true             # Enable caching
  directory = "~/.terrascan/cache"
  ttl = "24h"               # Cache results for 24 hours

[logging]
  level = "warn"            # Reduce log verbosity

[policy]
  # Use local policies to avoid network calls
  policy-path = ["~/.terrascan/policies"]
EOF

    # 3. Create performance monitoring script
    cat > ~/.terrascan/monitor-performance.sh << 'EOF'
#!/bin/bash
# Monitor Terrascan performance

monitor_scan() {
    local scan_dir="$1"
    local output_file="terrascan-performance-$(date +%s).log"

    echo "Monitoring Terrascan performance for: $scan_dir"

    # Start monitoring
    {
        echo "Timestamp,CPU%,Memory(MB),Files_Processed,Violations_Found"
        start_time=$(date +%s)

        while pgrep -f "terrascan" > /dev/null; do
            local pid=$(pgrep -f "terrascan")
| local cpu=$(ps -p $pid -o %cpu --no-headers 2>/dev/null |  | echo "0") |
| local mem=$(ps -p $pid -o rss --no-headers 2>/dev/null | awk '{print $1/1024}' |  | echo "0") |
            local timestamp=$(date +%s)
            local elapsed=$((timestamp - start_time))

            echo "$timestamp,$cpu,$mem,N/A,N/A"
            sleep 2
        done
    } > "$output_file" &

    local monitor_pid=$!

    # Run Terrascan with timing
    echo "Starting Terrascan scan..."
    time terrascan scan -d "$scan_dir" --config-path ~/.terrascan/performance-config.toml

    # Stop monitoring
    kill $monitor_pid 2>/dev/null

    echo "Performance monitoring completed: $output_file"
}

# Usage: monitor_scan /path/to/iac/files
EOF

    chmod +x ~/.terrascan/monitor-performance.sh

    echo "Performance optimizations applied"
}

# Benchmark different configurations
benchmark_terrascan() {
    local test_dir="$1"

    echo "Benchmarking Terrascan configurations..."

    # Test different cache settings
    cache_settings=("true" "false")

    for cache in "${cache_settings[@]}"; do
        echo "Testing with cache: $cache"

        # Create test config
        cat > /tmp/test-config.toml << EOF
[cache]
  enabled = $cache
  directory = "~/.terrascan/cache"
  ttl = "24h"
EOF

        start_time=$(date +%s)
        terrascan scan -d "$test_dir" --config-path /tmp/test-config.toml > /dev/null 2>&1
        end_time=$(date +%s)

        duration=$((end_time - start_time))
        echo "Cache $cache: ${duration}s"
    done

    # Test different log levels
    log_levels=("debug" "info" "warn" "error")

    echo "Testing different log levels..."
    for level in "${log_levels[@]}"; do
        echo "Testing log level: $level"

        start_time=$(date +%s)
        TERRASCAN_LOG_LEVEL=$level terrascan scan -d "$test_dir" > /dev/null 2>&1
        end_time=$(date +%s)

        duration=$((end_time - start_time))
        echo "Log level $level: ${duration}s"
    done
}

# Memory optimization for large scans
optimize_memory_usage() {
    echo "Optimizing memory usage for large scans..."

    # Split large directories into smaller chunks
    split_scan_directory() {
        local input_dir="$1"
        local chunk_size="${2:-100}"
        local output_dir="${3:-./scan_chunks}"

        mkdir -p "$output_dir"

        # Find all IaC files
        find "$input_dir" -name "*.tf" -o -name "*.yaml" -o -name "*.yml" -o -name "*.json" > /tmp/iac_files.txt

        # Split into chunks
        split -l "$chunk_size" /tmp/iac_files.txt "$output_dir/chunk_"

        echo "Directory split into chunks in: $output_dir"
    }

    # Process chunks sequentially
    process_chunks() {
        local chunk_dir="$1"
        local output_file="$2"

        echo "Processing chunks for memory optimization..."

        for chunk in "$chunk_dir"/chunk_*; do
            echo "Processing chunk: $(basename "$chunk")"

            # Create temporary directory for chunk
            temp_dir="/tmp/terrascan_chunk_$$"
            mkdir -p "$temp_dir"

            # Copy files from chunk to temp directory
            while IFS= read -r file; do
                if [ -f "$file" ]; then
                    cp "$file" "$temp_dir/"
                fi
            done < "$chunk"

            # Scan chunk
            terrascan scan -d "$temp_dir" --output json >> "$output_file"

            # Clean up
            rm -rf "$temp_dir"

            # Small delay to prevent memory buildup
            sleep 1
        done

        echo "All chunks processed. Results in: $output_file"
    }

    # Example usage
    # split_scan_directory "./large_infrastructure" 50 "./chunks"
    # process_chunks "./chunks" "chunked_results.json"
}

# Run optimizations
optimize_terrascan_performance

Problemas comunes

#!/bin/bash
# Terrascan troubleshooting guide

troubleshoot_terrascan() {
    echo "Terrascan Troubleshooting Guide"
    echo "==============================="

    # Check if Terrascan is installed
    if ! command -v terrascan &> /dev/null; then
        echo "❌ Terrascan not found"
        echo "Solution: Install Terrascan using one of these methods:"
        echo "  # Binary installation"
        echo "  curl -L \"\$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E \"https://.+?_Linux_x86_64.tar.gz\")\" > terrascan.tar.gz"
        echo "  tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz"
        echo "  sudo install terrascan /usr/local/bin && rm terrascan"
        echo ""
        echo "  # Package manager"
        echo "  brew install terrascan  # macOS/Linux"
        echo "  choco install terrascan # Windows"
        return 1
    fi

| echo "✅ Terrascan found: $(terrascan version 2>/dev/null |  | echo 'Version unknown')" |

    # Check configuration
    if [ ! -f ~/.terrascan/config.toml ]; then
        echo "⚠️  Configuration file not found"
        echo "Solution: Create default configuration"
        echo "  mkdir -p ~/.terrascan"
        echo "  terrascan init"
    else
        echo "✅ Configuration file exists"
    fi

    # Check policies
    if [ ! -d ~/.terrascan/policies ]; then
        echo "⚠️  Policies directory not found"
        echo "Solution: Initialize policies"
        echo "  mkdir -p ~/.terrascan/policies"
        echo "  # Download default policies from Terrascan repository"
    else
        echo "✅ Policies directory exists"
        policy_count=$(find ~/.terrascan/policies -name "*.rego" | wc -l)
        echo "   Found $policy_count policy files"
    fi

    # Check system resources
    available_memory=$(free -m | awk 'NR==2{printf "%.1f", $7/1024}')
    if (( $(echo "$available_memory < 1.0" | bc -l) )); then
        echo "⚠️  Low available memory: ${available_memory}GB"
        echo "Solution: Free up memory or use chunked scanning"
    else
        echo "✅ Available memory: ${available_memory}GB"
    fi

    # Check file descriptor limits
    fd_limit=$(ulimit -n)
    if [ "$fd_limit" -lt 1024 ]; then
        echo "⚠️  Low file descriptor limit: $fd_limit"
        echo "Solution: Increase file descriptor limit"
        echo "  ulimit -n 65536"
    else
        echo "✅ File descriptor limit: $fd_limit"
    fi

    # Test basic functionality
    echo "Testing basic functionality..."

    # Create test Terraform file
    cat > /tmp/test.tf << 'EOF'
resource "aws_s3_bucket" "test" {
  bucket = "test-bucket"
}
EOF

    # Test scan
    if terrascan scan -f /tmp/test.tf > /dev/null 2>&1; then
        echo "✅ Basic scan functionality working"
    else
        echo "❌ Basic scan functionality failed"
        echo "Solution: Check Terrascan installation and configuration"
    fi

    # Clean up
    rm -f /tmp/test.tf

    echo "Troubleshooting completed"
}

# Common error solutions
fix_common_terrascan_errors() {
    echo "Common Terrascan Errors and Solutions"
    echo "===================================="

    cat << 'EOF'
1. "terrascan: command not found"
   Solution: 
    - Download and install Terrascan binary
    - Add installation directory to PATH
    - Verify installation with: terrascan version

2. "failed to load policies"
   Solution:
    - Initialize Terrascan: terrascan init
    - Check policy directory: ~/.terrascan/policies
    - Download policies from official repository

3. "timeout exceeded" during scan
   Solution:
    - Increase timeout in config: timeout = "600s"
    - Split large directories into smaller chunks
    - Use performance-optimized configuration

4. "out of memory" errors
   Solution:
    - Increase system memory
    - Use chunked scanning for large directories
    - Reduce concurrent scans
    - Enable caching to reduce memory usage

5. "invalid IaC type" error
   Solution:
    - Specify correct IaC type: --iac-type terraform
    - Check file extensions and content
    - Use auto-detection by omitting --iac-type

6. "no violations found" (false negatives)
   Solution:
    - Check policy configuration
    - Verify IaC type detection
    - Use --verbose for detailed output
    - Check severity and confidence filters

7. "policy evaluation failed"
   Solution:
    - Validate custom policies with OPA
    - Check Rego syntax in custom policies
    - Update to latest Terrascan version
    - Review policy path configuration

8. "SSL certificate verification failed"
   Solution:
    - Update system CA certificates
    - Use --insecure flag for testing (not recommended for production)
    - Configure proxy settings if behind corporate firewall

9. "permission denied" errors
   Solution:
    - Check file and directory permissions
    - Run with appropriate user privileges
    - Verify write permissions for output directory

10. Slow scanning performance
    Solution:
    - Enable caching in configuration
    - Use local policy files
    - Reduce log verbosity
    - Optimize system resources
    - Use parallel scanning for multiple directories
EOF
}

# Performance diagnostics
diagnose_performance_issues() {
    echo "Diagnosing Terrascan Performance Issues"
    echo "======================================"

    # Check system load
| load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//') |
    echo "System load average: $load_avg"

    # Check available CPU cores
    cpu_cores=$(nproc)
    echo "Available CPU cores: $cpu_cores"

    # Check memory usage
    memory_info=$(free -h | grep "Mem:")
    echo "Memory info: $memory_info"

    # Check disk I/O
    if command -v iostat &> /dev/null; then
        echo "Disk I/O statistics:"
        iostat -x 1 1 | tail -n +4
    fi

    # Check file system performance
    echo "Testing file system performance..."
    test_dir="/tmp/terrascan_perf_test"
    mkdir -p "$test_dir"

    # Create test files
    for i in {1..100}; do
        echo "resource \"aws_s3_bucket\" \"test_$i\" { bucket = \"test-bucket-$i\" }" > "$test_dir/test_$i.tf"
    done

    # Time file operations
    start_time=$(date +%s.%N)
    find "$test_dir" -name "*.tf" | wc -l > /dev/null
    end_time=$(date +%s.%N)

    file_op_time=$(echo "$end_time - $start_time" | bc)
    echo "File operation time: ${file_op_time}s"

    # Clean up
    rm -rf "$test_dir"

    # Recommendations based on findings
    echo ""
    echo "Performance Recommendations:"
    echo "- Optimal memory: >= 4GB for large scans"
    echo "- Enable caching for repeated scans"
    echo "- Use SSD storage for better I/O performance"
    echo "- Consider chunked scanning for very large codebases"
}

# Main troubleshooting function
main() {
    troubleshoot_terrascan
    echo ""
    fix_common_terrascan_errors
    echo ""
    diagnose_performance_issues
}

# Run troubleshooting
main

Recursos y documentación

Recursos oficiales

Recursos comunitarios

Ejemplos de integración