关于 tf-best-practices
供迁移工作流使用的 AWS Terraform 共享指南与只读策略检查器,提供编写安全规则和机器可读的检查结果。它不会修改 Terraform 文件,也不管理工作流状态。
主要功能
- 01AWS Terraform 安全规则
- 02只读策略验证
- 03机器可读的检查报告
- 04可操作的违规详情
- 05零依赖静态 HCL 检查
适用场景
- 01指导 Terraform 生成
- 02检查生成的 Terraform 安全状态
- 03在完成前定位策略违规
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aws/ agent-toolkit-for-aws --skill tf-best-practices安装后在 Claude Code 中输入/tf-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignorefixtures/terraform-policy/bad-db-sg-public-quoted-port/vpc.tffixtures/terraform-policy/bad-db-sg-public/vpc.tffixtures/terraform-policy/bad-elasticache-cluster-redis-unencrypted/cache.tffixtures/terraform-policy/bad-elasticache-unencrypted/cache.tffixtures/terraform-policy/bad-heroku-eb-elasticache/cache.tffixtures/terraform-policy/bad-http-forward/compute.tffixtures/terraform-policy/bad-rds-public-brace-in-comment/main.tffixtures/terraform-policy/bad-rds-public-closing-brace/main.tffixtures/terraform-policy/bad-rds-public-interpolated-brace/rds.tffixtures/terraform-policy/bad-rds-public-unencrypted/database.tffixtures/terraform-policy/bad-sg-public-ipv6/vpc.tffixtures/terraform-policy/bad-sg-public-ssh/vpc.tffixtures/terraform-policy/bad-wildcard-iam-listform/security.tffixtures/terraform-policy/bad-wildcard-iam/security.tffixtures/terraform-policy/good-db-sg-scoped/vpc.tffixtures/terraform-policy/good-elasticache-cluster-memcached/cache.tffixtures/terraform-policy/good-elasticache-cluster-redis-encrypted/cache.tffixtures/terraform-policy/good-elasticache-encrypted/cache.tffixtures/terraform-policy/good-heroku-eb-codepipeline/pipeline.tffixtures/terraform-policy/good-heroku-eb-loadbalanced/compute.tfdatabase.tfsecurity.tffixtures/terraform-policy/good-heroku-eb-only/compute.tffixtures/terraform-policy/good-heroku-eb-singleinstance/compute.tffixtures/terraform-policy/good-https-redirect/compute.tffixtures/terraform-policy/good-iam-scoped-list/security.tffixtures/terraform-policy/good-internet-nlb/compute.tffixtures/terraform-policy/good-quoted-port-https/compute.tffixtures/terraform-policy/good-rds-private-encrypted/database.tf详细介绍
tf-best-practices — 生成式 IaC 安全态势规则 + 只读策略门禁
共享的编写指南和判定结果生成器,而非工作流。它针对生成 AWS Terraform 的阶段回答两个问题:
- 编写前——“生成的
terraform/必须遵循哪些安全态势要求?” (安全态势规则 +baseline.tf账户加固规范) - 编写后——“生成的
terraform/是否通过策略检查?”(确定性的、 只读判定结果 + 机器可读报告)
路由——根据你的上下文加载相应部分
调用方的 Generate 流程会在两个接入点调用此技能,中间由调用方自行完成 Terraform 编写工作。调用方加载此技能时会说明自己当前所处的接入点,并读取对应部分:
| 调用方上下文 | 加载 | 原因 |
|---|---|---|
即将编写 terraform/(编写前) | 第 1 部分 → references/security-posture-rules.md | AWS 编写规则,规定“应生成哪些内容”(门禁强制执行 + 仅供编写参考 + 按合规要求启用)。 |
terraform/ 已编写,准备验证(编写后) | 第 2 部分 → references/terraform-validation.md + 运行门禁脚本 | fmt → init → validate → policy 协议和只读判定结果。 |
此技能中的所有内容均与源云无关(纯 AWS Terraform)。任何 GCP/Heroku 检测或制品读取都由调用方负责;规则需要调用方已知的信息时(例如已声明的合规框架),调用方会将其作为调用方上下文信号传入——参见 references/security-posture-rules.md § 调用方上下文信号。
边界(请先阅读)
此单元是判定结果生成器,绝不修改内容。它唯一的写入对象是所要求生成的 JSON 判定结果。具体来说,它不得:
- 编辑、格式化或重写任何
.tf文件(修复由调用方负责), - 读取或写入
.phase-status.json或任何运行状态文件(由解释器负责), - 决定阶段是否可以完成,或提示用户(由调用方策略负责)。
调用方(迁移技能的 Generate 阶段)负责:编辑其生成的 .tf 文件以修复并重试、自动应用 terraform fmt、重试/跳过/中止提示、阶段完成门禁,以及所有 .phase-status.json 写入。有关判定结果如何影响这些决策,请参见使用此技能的技能中的 Generate 阶段。
使用方:
gcp-to-aws(散文式 Generate)和heroku-to-aws(DSL Generate)。此契约与源无关;每个调用方都会按自身的 Generate 形式接入这两个接入点——gcp-to-aws将其作为散文步骤,heroku-to-aws则将其作为片段步骤,并由解释器执行一个失败即关闭的_postconditions断言。
第 1 部分 — 编写规范(编写 terraform/ 前加载)
生成符合 references/security-posture-rules.md 中规范的 Terraform。
这些是“符合要求的 AWS Terraform 应是什么样”的规则。遵循这些规则,即可从一开始就通过第 2 部分的检查。本单元不会读取调用方的构件——它只使用调用方传入的上下文信号。
范围。
security-posture-rules.md分为三个层级:
- 检查强制执行(第 2 部分通过静态检查验证):ALB TLS、数据库不公开、RDS + ElastiCache 静态加密、禁止向公网开放 DB 端口、禁止向公网开放管理/数据存储端口、禁止通配符 IAM。
- 仅适用于编写阶段(无法通过检查验证,但仍为必需):
deletion_protection、通过 Secrets Manager 管理主密码、S3 强化、Fargate/EKS/ECR 设置、放置在私有子网、备份、基线监控。- 合规条件适用(调用方声明
soc2/pci/hipaa/fedramp时生成):VPC 流日志、S3 访问日志、密钥轮换、客户托管的 KMS。仍属于调用方自身的生成职责(今后可考虑迁移到此处):账户强化
baseline.tf层(CloudTrail、GuardDuty、Config、Security Hub)。
第 2 部分 — 策略检查(编写 terraform/ 后运行)
针对生成的目录运行只读检查器。相对于插件根目录解析脚本路径($PLUGIN_ROOT/skills/tf-best-practices/scripts/...),与插件其他脚本使用相同的约定:
python3 "$PLUGIN_ROOT/skills/tf-best-practices/scripts/validate-terraform-policy.py" "$TERRAFORM_DIR" --json "$VERDICT_PATH"
$TERRAFORM_DIR— 必需,由调用方提供:生成的terraform/目录(例如$MIGRATION_DIR/terraform)。此技能不会为其设置默认值或查找它——调用方始终会传入其写入 Terraform 的路径。--json $VERDICT_PATH— 可选;将机器可读的判定写入文件,供调用方合并到自己的validation-report.json中。
策略检查是更大验证流程(fmt → init → validate → policy)中的一个阶段。完整协议——包括离线回退行为,以及如何将策略判定映射到 validation-report.json——记录在 references/terraform-validation.md 中。该协议仅作说明:调用方负责执行 fmt/init/validate、修复并重试的循环,以及写入报告;本单元仅提供只读策略阶段和判定格式。
退出码 → 调用方操作
| 退出码 | stdout | 含义 | 调用方操作 |
|---|---|---|---|
0 | POLICY_OK | 符合规范 | 继续 |
1 | POLICY_FAIL | 存在违规项 | 读取 violations[],编辑指定的 .tf 位置,然后重新运行(遵循调用方的重试次数限制) |
2 | (用法错误) | 路径错误/IO 错误 | 告知用户;不要视为通过 |
判定格式(--json)
{
"check": "policy",
"policy_status": "POLICY_OK | POLICY_FAIL",
"violations": [
{
"check": "policy",
"rule": "alb_https_listener | alb_http_redirect | no_tf_files",
"file": "compute.tf",
"line": 7,
"severity": "error",
"summary": "human-readable violation",
"fix_hint": "concrete remediation the caller can apply"
}
]
}
每个 violations[] 条目都是可操作的证据——file + line + fix_hint 会明确告知调用方要编辑的位置。由调用方应用修改;本单元仅负责报告。
当前强制执行的策略规则
每条规则在存在歧义时都默认放行——只有存在明确且位于代码块内的字面证据时才会触发,因此不会误拦截有效的技术栈(对于调用方,POLICY_FAIL 是硬性完成门槛,因此误报会阻止真实迁移)。
面向互联网的 ALB TLS 配置(当 internal 缺失、为 false 或由变量驱动时,ALB 会被视为面向互联网——安全优先):
alb_https_listener— 必须在443上配置 HTTPS 监听器,并包含certificate_arn和forward操作。alb_http_redirect— HTTP:80监听器必须将流量redirect到 HTTPS,不能forward到目标。内部 ALB(internal = true)不受此规则约束。
这些规则无法识别 Elastic Beanstalk ALB。 ALB 规则会检查独立的
aws_lb_listener代码块。EB 的 LoadBalanced 环境通过aws_elastic_beanstalk_environment的setting代码块创建 ALB,而静态检查器不会读取这些代码块——因此,纯 EB 设计会因缺少待检查的监听器而通过 ALB 规则。也就是说,EB 监听器/TLS 配置仅在编写时检查,不受门禁强制执行。(Fixturegood-heroku-eb-only和good-heroku-eb-singleinstance对此进行了说明;good-heroku-eb-loadbalanced包含独立的 ALB,因此会针对真实代码块执行监听器规则。)
托管数据库暴露与加密(aws_db_instance、aws_rds_cluster):
rds_not_public— 不得设置publicly_accessible = true(缺失或由变量驱动时默认放行)。rds_encryption_at_rest— 必须设置storage_encrypted = true;缺失或字面值为false时会触发规则,由变量驱动时默认放行。(RDS 默认不加密。)不检查 S3(自 2023 年 1 月起,默认使用 SSE-S3)。
ElastiCache 加密(aws_elasticache_replication_group、Redis aws_elasticache_cluster):
elasticache_encryption_at_rest— 复制组必须设置at_rest_encryption_enabled = true;缺失或字面值为false时会触发规则,由变量驱动时默认放行。elasticache_cluster_encryption— Redis 引擎的aws_elasticache_cluster(单节点:engine = "redis",且没有replication_group_id)必须同时设置at_rest_encryption_enabled = true和transit_encryption_enabled = true;任一项缺失或字面值为false时都会触发规则,由变量驱动时默认放行。engine = "memcached"的集群(以及引擎由变量驱动或未指定的集群)不受此规则约束——Memcached 不支持这些属性。
安全组入站规则:
db_sg_no_public_ingress—aws_security_group中覆盖5432/3306的内联入站规则不得允许0.0.0.0/0或::/0。sg_no_public_admin_ingress— 内联入站规则不得向0.0.0.0/0或::/0开放经过筛选、绝不应公开的管理/数据存储端口(22、3389、6379、11211、27017、9200/9300、5601)。Web(80/443)和应用/游戏端口不会被标记;数据库端口由上述规则处理。两条规则都会分别检查cidr_blocks和ipv6_cidr_blocks,因此无害的 IPv4 列表不会掩盖开放的 IPv6 列表。两条规则均对独立的aws_security_group_rule/aws_vpc_security_group_ingress_rule资源默认放行(不会进行关联检查)。
IAM 最小权限原则(aws_iam_policy、aws_iam_role_policy、aws_iam_group_policy、aws_iam_user_policy):
no_wildcard_iam—Allow语句不得将Action/Resource设为"*"。唯一的有限例外是单独的elasticbeanstalk:CreateStorageLocation语句,其Resource = "*",因为 AWS 不支持为该操作配置资源级权限。aws_iam_policy_document数据源和角色信任策略默认放行。
该检查器是一个零依赖的静态 HCL 读取器(无需运行
terraform init,也无需下载提供程序)——即使无法连接注册表,也能运行。它通过匹配大括号深度来识别嵌套代码块,因此,使用嵌套forward { ... }代码块编写的有效 HTTPS 监听器不会被误判为失败。
测试样例(也是检查器的回归测试套件)
fixtures/terraform-policy/ 存放供
scripts/test_validate_terraform_policy.py 使用的特意设计的 Terraform:
bad-http-forward/— 面向互联网的 ALB 转发明文 HTTP → 必须为POLICY_FAIL。internal-alb-only/— 使用 HTTP 的内部 ALB → 必须为POLICY_OK(内部允许使用 HTTP)。good-https-redirect/— 正确模式 →POLICY_OK。
这些都是故意不符合规范的测试数据(绝不会部署)。它们通过 .checkov.yaml 中的 skip-path 从整个仓库的
checkov 扫描中排除;请勿对其进行“加固”——这会破坏断言失败路径的测试。
验证
# from skills/tf-best-practices/
uv run --python 3.12 --with pytest python -m pytest scripts/test_validate_terraform_policy.py -q