云资源编排体检
在 terraform plan / apply 之前,先给基础设施即代码做一次结构化自查:把云上最贵、
最危险的坑一次列清楚——密钥被写进 .tf、安全组对 0.0.0.0/0 全开、对象存储对外公开、
IAM 用了通配符 *、库表盘没加密、state 存在本地、数据库挂了公网地址、
provider 没锁版本、资源没有标签……
只给结构化提示,不替你改代码——是否采纳取决于资源用途、账号基线与合规要求。
适用场景
- 用户给出 / 起草了
.tf文件、模块或整仓terraform/目录,说「帮我看看有没有问题」。 - 执行
apply之前、或接入 CI(plan/apply 流水线)之前做一次自查。 - 想批量扫一个仓库里所有 HCL,找出优先级最高的风险项。
- 排查「state 冲突」「资源被误删」「成本说不清」类问题时的第一轮体检。
不适用:terraform validate / plan 的语义校验(本工具不解析表达式求值);CVE 与依赖漏洞
扫描;云账号实际配置(本工具只看代码文本,不联网、不调用云 API);OpenTofu / Terragrunt
专有语法(terragrunt.hcl 不在解析范围内)。
怎么用
# 单个文件
python3 scripts/terraform_lint.py --file main.tf
# 整个目录(自动发现 *.tf,跳过 .terraform / .git / .terragrunt-cache)
python3 scripts/terraform_lint.py --file ./terraform
# 多个输入
python3 scripts/terraform_lint.py --file main.tf --file modules/vpc
# 输出 JSON(便于接 CI)
python3 scripts/terraform_lint.py --file ./terraform --json
# 用内置问题样例看效果(命中高/中/低三档)
python3 scripts/terraform_lint.py --sample
输入格式
- 标准 HCL(Terraform)。正确处理
#、//、/* */注释、字符串转义与 heredoc。 - 解析粒度到「块 - 属性」:能识别
resource/data/variable/output/
module/provider/terraform/backend/locals以及ingress/validation/
default_tags/lifecycle等嵌套块,并给出精确行号与字段。 - 目录模式下会递归发现
*.tf,并跳过.git、.terraform、.terragrunt-cache、
node_modules、__pycache__、vendor。 - 只读输入,不修改任何文件。
规则清单
| 规则码 | 含义 | 严重度 |
|---|---|---|
T1 HARDCODED_SECRET |
硬编码密钥 / 口令(命中值掩码输出) | 高 |
T2 SECRET_VAR_NOT_SENSITIVE |
敏感变量未标记 sensitive = true |
中 |
T3 SECRET_VAR_DEFAULT |
敏感变量带明文默认值(掩码输出) | 高 |
T4 SG_OPEN_ALL_PORTS |
安全组对 0.0.0.0/0 开放全部端口 / protocol = "-1" |
高 |
T5 SG_OPEN_SENSITIVE_PORT |
安全组对 0.0.0.0/0 开放敏感端口(22/3389/3306/5432/6379…) |
高 |
T6 SG_OPEN_INGRESS |
安全组入站对 0.0.0.0/0 开放(非敏感端口) |
中 |
T7 IAM_WILDCARD_ACTION |
IAM 策略 Action = "*" |
高 |
T8 IAM_WILDCARD_RESOURCE |
IAM 策略 Resource = "*" |
中 |
T9 STORAGE_PUBLIC_ACL |
存储桶使用公开 ACL(public-read(-write)) |
高 |
T10 S3_NO_PUBLIC_ACCESS_BLOCK |
存储桶缺少公开访问阻断 | 中 |
T11 STORAGE_NO_ENCRYPTION |
存储资源(S3 / EBS)未启用加密 | 高 |
T12 STORAGE_NO_VERSIONING |
存储桶未启用版本控制 | 中 |
T13 DB_PUBLIC |
数据库 publicly_accessible = true |
高 |
T14 DB_NO_ENCRYPTION |
数据库未启用存储加密 | 高 |
T15 DB_NO_DELETE_PROTECTION |
数据库缺少删除保护 | 中 |
T16 FORCE_DESTROY |
资源启用 force_destroy = true |
中 |
T17 NO_REMOTE_BACKEND |
未配置远端 state 后端(本地 state) | 高 |
T18 BACKEND_NO_ENCRYPT |
远端 state 后端未启用加密 | 中 |
T19 BACKEND_NO_LOCK |
远端 state 后端未启用状态锁 | 中 |
T20 PROVIDER_UNPINNED |
provider 未锁定版本 | 中 |
T21 RESOURCE_NO_TAGS |
资源缺少标签(且无 default_tags) |
低 |
T22 VAR_NO_TYPE |
变量缺少 type |
中 |
T23 VAR_NO_DESCRIPTION |
变量缺少 description |
低 |
T24 VAR_NO_VALIDATION |
变量缺少 validation(input 校验) |
低 |
T25 OUTPUT_NO_DESCRIPTION |
输出缺少 description |
低 |
T26 NAME_INVALID |
资源 / 数据源 / 模块名不合规 | 中 |
T27 DUPLICATE_RESOURCE |
重复的资源定义 | 中 |
T28 DEPRECATED_PARAM |
使用已弃用参数 | 低 |
规则是启发式的:命中只代表「可能有问题」,需结合实际情况判断。
评分口径
整体与每个文件独立评分:得分 = max(0, 100 − (高风险×15 + 中风险×5 + 低风险×2))。
结论档:≥ 90 优秀 / 75–89 良好 / 60–74 一般 / < 60 较差。
分数只是相对参考,用于横向比较不同代码的整洁度,不代表真实安全水平。
输出示例(节选)
云资源编排体检报告
====================================================================
受检文件:
· main.tf 命中 25 项 评分 0/100
· variables.tf 命中 9 项 评分 60/100
问题合计 34 项:高 12 · 中 11 · 低 11
评分:0/100 结论:较差
结论:存在 12 项高风险问题,建议修复后再执行 terraform apply
—— 高风险(12 项)——
【高】[T1] 硬编码密钥 / 口令 (定位:main.tf:4)
· 命中:access_key = "AK******LE"
· 说明:密钥、口令、Token 直接写成字面量会进入版本库与 state 文件……
· 建议:改用变量(密钥类变量加 sensitive = true)或接入密钥管理服务……
【高】[T5] 安全组向 0.0.0.0/0 开放敏感端口 (定位:main.tf:20)
· 命中:ingress 对 0.0.0.0/0 开放高危端口 22
· 说明:SSH / RDP / 数据库 / 缓存 / 容器 API 等高危端口对全网开放……
· 建议:收敛来源 CIDR,或改用堡垒机 / SSM Session Manager / 私网访问。
退出码:0 未见问题 / 1 存在问题或用法错误。
限制与免责
- 纯标准库 Python,只读输入文件,无网络请求,无
subprocess/eval/os.system。 - 报告中的疑似密钥一律掩码输出(只留首尾少量字符),避免二次暴露;但仍请勿把含真实
密钥的报告外发。 - 不做语义校验:本工具不展开变量、不解析表达式、不推断
variable的默认值对资源的实际
影响;for_each/dynamic等动态结构不会被完整建模。 - 不做漏洞与合规扫描:不内置、不联网查询 CVE 库,不对「是否符合某等保 / CIS 基线」作断言。
- 规则是启发式的,存在误报与漏报:例如存储桶加密可能由账号级默认加密兜底、
0.0.0.0/0:80
对公网 Web 是有意为之、某些acl需与业务共存等。 - 云安全还涉及账号权限、网络策略、运行时防护、密钥轮换等,本工具只覆盖编排代码文本这一层。
- 本包为开源改编作品,来源与改动见
来源与许可.md,遵守 MIT 许可证(LICENSE.md)。
上游署名
本工具改编自开源项目 alirezarezvani/claude-skills
中 engineering/terraform-patterns 的检查思路(MIT License, Copyright © 2025 Alireza Rezvani),
代码已完全重写。详见 来源与许可.md。
依赖
仅需 Python 3.8+,使用标准库,无需联网、无需安装第三方包。