# Auditing Terraform Infrastructure For Security

> 使用 Checkov、tfsec、Terrascan 和 OPA/Rego 策略，审计 Terraform 基础设施即代码中的安全错误配置， 在云部署前检测过度宽松的 IAM 策略、公开资源暴露、缺失加密和不安全的默认设置。

- Skill: `killvxk/auditing-terraform-infrastructure-for-security` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/auditing-terraform-infrastructure-for-security`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/auditing-terraform-infrastructure-for-security/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/auditing-terraform-infrastructure-for-security

---


# 审计 Terraform 基础设施安全

## 适用场景

- 将安全扫描集成到 Terraform 部署的 CI/CD 流水线时
- 在应用前审查 Terraform 计划和模块的安全最佳实践时
- 为云基础设施配置构建策略即代码（policy-as-code）护栏时
- 审计现有 Terraform 状态文件以识别已部署的错误配置时
- 跨多个 Terraform 项目强制执行组织安全标准时

**不适用于**：运行时安全监控（使用 CSPM 工具）、应用安全测试（使用 SAST/DAST 工具），或部署后的云配置漂移检测（使用 AWS Config 或 Azure Policy）。

## 前置条件

- 安装 Checkov（`pip install checkov`）
- 安装 tfsec（`brew install tfsec` 或从 GitHub 下载二进制文件）
- 安装 Terrascan（`brew install terrascan`）
- Terraform v1.0+，用于生成计划
- OPA（Open Policy Agent），用于自定义策略强制执行
- 包含待审计 Terraform 代码的 Git 仓库

## 工作流程

### 步骤 1：使用 Checkov 扫描 Terraform 代码

运行 Checkov 进行全面的 IaC 安全扫描，使用内置和自定义策略。

```bash
# 扫描 Terraform 目录
checkov -d ./terraform/ --framework terraform

# 按特定检查类别扫描
checkov -d ./terraform/ --check CKV_AWS_18,CKV_AWS_19,CKV_AWS_20,CKV_AWS_21

# 扫描并以 JSON 格式输出结果
checkov -d ./terraform/ --output json > checkov-results.json

# 扫描 Terraform 计划文件以获得更准确的分析
terraform init && terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
checkov -f tfplan.json --framework terraform_plan

# 跳过特定检查（附带理由）
checkov -d ./terraform/ --skip-check CKV_AWS_145 \
  --bc-api-key $BRIDGECREW_API_KEY

# 扫描 Terraform 模块
checkov -d ./modules/ --framework terraform --compact

# 列出所有可用检查
checkov --list --framework terraform | grep CKV_AWS
```

### 步骤 2：使用 tfsec 扫描 Terraform 专项问题

使用 tfsec 进行 Terraform 原生安全分析，提供详细的修复指南。

```bash
# 扫描 Terraform 目录
tfsec ./terraform/

# 以最低严重性阈值扫描
tfsec ./terraform/ --minimum-severity HIGH

# 以 JSON 格式输出供 CI/CD 处理
tfsec ./terraform/ --format json > tfsec-results.json

# 使用自定义检查扫描
tfsec ./terraform/ --custom-check-dir ./custom-checks/

# 排除特定规则
tfsec ./terraform/ --exclude-downloaded-modules \
  --exclude aws-s3-enable-bucket-logging

# 扫描并对特定严重性失败
tfsec ./terraform/ --minimum-severity CRITICAL --soft-fail

# 生成 SARIF 输出供 GitHub Security 选项卡使用
tfsec ./terraform/ --format sarif > tfsec.sarif
```

### 步骤 3：运行 Terrascan 进行多框架合规检查

执行 Terrascan 对 CIS、NIST 和 SOC 2 框架进行合规检查。

```bash
# 对 CIS AWS 基准扫描 Terraform
terrascan scan -t aws -i terraform -d ./terraform/ \
  --policy-type aws --verbose

# 对特定合规框架扫描
terrascan scan -t aws -i terraform -d ./terraform/ \
  --policy-type aws \
  --categories "Compliance Validation"

# 以 JSON 格式输出
terrascan scan -t aws -i terraform -d ./terraform/ \
  --output json > terrascan-results.json

# 扫描 Terraform 计划
terrascan scan -t aws -i terraform \
  --iac-file tfplan.json \
  --iac-type tfplan

# 列出可用策略
terrascan scan --list-policies -t aws
```

### 步骤 4：创建自定义 OPA 策略以满足组织标准

编写 Rego 策略以满足组织特定的安全要求。

```rego
# policy/aws_s3_encryption.rego
package terraform.aws.s3

deny[msg] {
    resource := input.resource.aws_s3_bucket[name]
    not resource.server_side_encryption_configuration
    msg := sprintf("S3 存储桶 '%s' 必须启用服务器端加密", [name])
}

# policy/aws_iam_no_wildcards.rego
package terraform.aws.iam

deny[msg] {
    resource := input.resource.aws_iam_policy[name]
    statement := resource.policy.Statement[_]
    statement.Action == "*"
    statement.Effect == "Allow"
    msg := sprintf("IAM 策略 '%s' 不得使用通配符 (*) 操作", [name])
}

deny[msg] {
    resource := input.resource.aws_iam_policy[name]
    statement := resource.policy.Statement[_]
    statement.Resource == "*"
    statement.Effect == "Allow"
    contains(statement.Action[_], "*")
    msg := sprintf("IAM 策略 '%s' 对通配符资源使用了过度宽松的操作", [name])
}

# policy/aws_no_public_ingress.rego
package terraform.aws.security_group

deny[msg] {
    resource := input.resource.aws_security_group_rule[name]
    resource.type == "ingress"
    resource.cidr_blocks[_] == "0.0.0.0/0"
    resource.from_port <= 22
    resource.to_port >= 22
    msg := sprintf("安全组规则 '%s' 允许来自 0.0.0.0/0 的 SSH 访问", [name])
}
```

```bash
# 对 OPA 策略评估 Terraform 计划
terraform show -json tfplan | opa eval \
  --data ./policy/ \
  --input /dev/stdin \
  "data.terraform.aws" \
  --format pretty

# 使用 Conftest 进行更简便的 OPA 策略测试
conftest test tfplan.json --policy ./policy/ --output json
```

### 步骤 5：将安全扫描集成到 CI/CD 流水线

将 IaC 安全扫描作为强制性 CI/CD 门控。

```yaml
# GitHub Actions：Terraform 安全流水线
name: Terraform Security Scan
on:
  pull_request:
    paths: ['terraform/**']

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3

      - name: Terraform Init & Plan
        run: |
          cd terraform/
          terraform init
          terraform plan -out=tfplan
          terraform show -json tfplan > tfplan.json

      - name: Checkov Scan
        uses: bridgecrewio/checkov-action@master
        with:
          directory: terraform/
          framework: terraform
          output_format: sarif
          output_file_path: checkov.sarif
          soft_fail: false

      - name: tfsec Scan
        uses: aquasecurity/tfsec-action@v1.0.0
        with:
          working_directory: terraform/
          soft_fail: false

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

      - name: OPA Policy Check
        run: |
          conftest test terraform/tfplan.json \
            --policy ./policy/ \
            --output json
```

### 步骤 6：扫描 Terraform 状态文件中已部署的错误配置

审计当前 Terraform 状态以识别已部署的安全问题。

```bash
# 将当前状态导出为 JSON
terraform show -json > terraform-state.json

# 使用 Checkov 扫描状态文件
checkov -f terraform-state.json --framework terraform_plan

# 查询状态中的特定安全问题
terraform state list | while read resource; do
  terraform state show "$resource" 2>/dev/null | grep -i "public\|0.0.0.0\|encrypt.*false\|password"
done

# 查找缺少必要标签的资源
terraform state list | grep aws_instance | while read resource; do
  tags=$(terraform state show "$resource" | grep -A20 "tags")
  if ! echo "$tags" | grep -q "Environment"; then
    echo "缺少标签: $resource 缺少 'Environment' 标签"
  fi
done
```

## 核心概念

| 术语 | 定义 |
|------|------------|
| 基础设施即代码（Infrastructure as Code） | 通过声明性配置文件（Terraform、CloudFormation）而非手动控制台操作来管理云基础设施的实践 |
| 策略即代码（Policy as Code） | 将安全和合规策略表示为可执行代码（Rego、Python），可对基础设施定义进行自动化评估 |
| 左移安全（Shift Left Security） | 通过在部署前扫描 IaC 而非配置后审计，将安全检查提前到开发生命周期的早期阶段 |
| Terraform 计划（Terraform Plan） | Terraform 将要进行的变更预览，可导出为 JSON 在应用前进行安全扫描 |
| Checkov | 开源 IaC 静态分析工具，支持 Terraform、CloudFormation、Kubernetes 和 Docker，内置 1000+ 策略 |
| OPA/Rego | Open Policy Agent 及其策略语言 Rego，用于定义对结构化数据输入进行评估的自定义安全规则 |

## 工具与系统

- **Checkov**：综合 IaC 扫描器，为 Terraform、CloudFormation、Kubernetes、ARM 和 Dockerfile 提供 1000+ 策略
- **tfsec**：Terraform 专用静态分析工具，提供详细修复指南和 SARIF 输出
- **Terrascan**：多 IaC 扫描器，支持合规框架（CIS、NIST、SOC 2）和策略即代码
- **OPA/Conftest**：自定义策略引擎，使用 Rego 语言定义组织特定的安全规则
- **Bridgecrew**：基于 Checkov 构建的商业平台，提供漂移检测和供应链安全

## 常见场景

### 场景：为现有 Terraform CI/CD 流水线添加安全门控

**场景背景**：DevOps 团队通过 GitHub Actions 中的 Terraform 部署基础设施，但没有安全扫描。近期审计发现多个 S3 存储桶未加密，安全组允许来自互联网的 SSH 访问。

**方法**：
1. 在 GitHub Actions 工作流中将 Checkov 添加为第一道安全门控
2. 运行 `checkov -d ./terraform/` 建立当前发现的基线
3. 分类现有发现：修复严重问题，为高风险问题创建工单，抑制可接受的风险
4. 添加 tfsec 作为 Terraform 专项检查的二级扫描器
5. 为组织标准编写自定义 OPA 策略（必要标签、命名规范）
6. 配置流水线以阻止含严重或高风险发现的 PR
7. 生成 SARIF 报告以集成 GitHub Security 选项卡

**常见陷阱**：在现有项目中添加安全扫描最初会产生数百条发现。逐步实施：先从仅阻止严重问题开始，再扩展到高风险问题。对有意为之的例外使用内联抑制注释（`#checkov:skip=CKV_AWS_18:静态网站的公开存储桶`），并附上文档化的理由。

## 输出格式

```
Terraform 安全审计报告
==================================
仓库: acme-corp/infrastructure
分支: main
扫描日期: 2026-02-23
工具: Checkov 3.x, tfsec 1.x, OPA 自定义策略

扫描结果:
  Checkov 检查通过:    187
  Checkov 检查失败:     34
  tfsec 检查通过:      156
  tfsec 检查失败:       28
  OPA 自定义策略:       12 通过，3 失败

严重发现:
[TF-001] 未加密的 S3 存储桶
  文件: modules/storage/main.tf:24
  资源: aws_s3_bucket.data_lake
  检查: CKV_AWS_19
  修复: 添加 server_side_encryption_configuration 块

[TF-002] 安全组允许来自 0.0.0.0/0 的 SSH 访问
  文件: modules/network/security.tf:45
  资源: aws_security_group_rule.ssh_access
  检查: CKV_AWS_24
  修复: 将 cidr_blocks 限制为堡垒机子网

[TF-003] IAM 策略使用通配符操作
  文件: modules/iam/policies.tf:12
  资源: aws_iam_policy.developer_policy
  检查: CKV_AWS_1
  修复: 将操作范围缩减到所需的特定服务

各严重程度摘要:
  严重:  6 条发现
  高:   14 条发现
  中:   28 条发现
  低:   18 条发现
  信息:  12 条发现
```

