适用场景
Terraform IaC 安全扫描适用于以下场景:
- 基础设施代码合入前自动检测高危配置:S3 桶公开访问、安全组放行 0.0.0.0/0、磁盘未加密等;
- 在 CI/CD 流水线中设置质量门禁,阻止不合规的 Terraform 计划进入生产环境;
- 接手存量基础设施代码时做一次全面基线体检;
- 满足等保、ISO 27001 等合规审计对云资源配置的留痕要求。
前置条件
- Terraform 1.5+(
terraform -version验证); - tfsec 与 Checkov 任选其一或都装:tfsec 提供 Docker/二进制安装,Checkov 依赖 Python 3.8+;
- 一个包含风险配置的测试模块(下文提供);
- CI 环境(本文以 GitHub Actions 为例)。
原理说明
两类工具都属于静态分析:不调用云 API,直接解析 .tf 文件构建的资源图,对照内置策略库(CIS Benchmark、AWS/Azure/GCP 最佳实践)逐项检查。tfsec(现已并入 Aqua Trivy,命令保留)专注 Terraform、速度快、输出友好;Checkov 支持面更广,覆盖 Terraform、CloudFormation、Kubernetes、Dockerfile 等框架,并支持用 Python/YAML 编写自定义策略。两者都返回非零退出码表示存在高危问题,这正是 CI 门禁的判定依据。
操作步骤
1. 准备含风险的示例代码
resource "aws_s3_bucket" "data" {
bucket = "wafai-demo-data"
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = false
block_public_policy = false
}
resource "aws_security_group_rule" "open_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = "sg-0123456789abcdef0"
}
resource "aws_ebs_volume" "app" {
availability_zone = "ap-northeast-1a"
size = 100
}
示例包含三个典型问题:S3 允许公开访问、SSH 对全网开放、EBS 卷未加密。
2. 安装并运行 tfsec
# macOS
brew install tfsec
# Linux 一键安装
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash
# Docker 方式运行
docker run --rm -v "$PWD:/scan" aquasec/tfsec /scan
tfsec .
tfsec 会输出每条问题的严重级别、规则编号(如 aws-s3-enable-bucket-encryption)与修复建议链接。
3. 安装并运行 Checkov
pip install checkov
checkov -d .
# 只输出失败项,降低日志噪音
checkov -d . --compact
Checkov 输出带 CKV_AWS_* 编号的检查结果,可用 -c CKV_AWS_20,CKV_AWS_23 只跑指定规则。
4. 处理误报:行内豁免
resource "aws_ebs_volume" "app" {
availability_zone = "ap-northeast-1a"
size = 100
# checkov:skip=CKV_AWS_3:临时卷不存敏感数据,季度评审
# tfsec:ignore:aws-ebs-encrypt-encrypted-volume
}
豁免注释必须写明理由,便于后续审计复查,避免豁免被无限期滥用。
5. 集成到 GitHub Actions
name: iac-security
on:
pull_request:
paths: ["**/*.tf"]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: tfsec
uses: aquasecurity/tfsec-pr-commenter-action@v1.3.1
with:
github_token: ${{ github.token }}
- name: Checkov
uses: bridgecrewio/checkov-action@v12
with:
directory: .
framework: terraform
output_format: cli
配置验证
按建议修复示例问题(开启 S3 block_public_acls、收紧安全组 CIDR、给 EBS 加 encrypted = true)后重新运行:
tfsec . && echo "tfsec PASS"
checkov -d . ; echo "checkov exit=$?"
两个命令退出码均为 0、输出 “0 failures” 即代表门禁通过。可以将此步骤设为 PR 必检项,实现”不通过则不可合入”。
常见问题
FAQ 1:扫描结果误报太多,团队开始无视告警怎么办?
采用分级策略:CRITICAL/HIGH 阻断合入,MEDIUM 以下先告警;确属误报的用行内豁免并注明到期日期。每月复查豁免清单,删除已失效的豁免项。
FAQ 2:tfsec 和 Checkov 应该选哪个?
纯 Terraform 项目追求速度与 CI 集成简洁,选 tfsec;技术栈包含 CloudFormation、Kubernetes、Helm 等多类 IaC,或需要自定义 Python 策略与对接 Bridgecrew 平台,选 Checkov。两者同时运行成本不高,互为补充可以覆盖更多规则。
总结
Terraform IaC 安全扫描把基础设施风险拦截在”计划尚未执行”的阶段,成本远低于事后整改。落地三步走:先用 tfsec/Checkov 对存量代码做基线体检,再把扫描嵌入 PR 流水线设置严重级别门禁,最后通过带备注的行内豁免机制控制误报影响。持续维护策略库版本与豁免清单,才能让 IaC 安全真正成为研发流程的一部分而非摆设。