概述
成本分摊依赖少量标签存在且取值一致。资源在缺少标签的情况下上线,账单照样产生,却无法按团队或服务拆分,问题会安静地累积,直到有人需要回答预算问题。在基础设施 plan 阶段拦截,远比季度末对账便宜。策略文件同时充当标签规范的文档,比无人阅读的 wiki 更可靠。
步骤
- 将 plan 转为 JSON 并执行标签策略:
terraform show -json tfplan > plan.json
conftest test plan.json --policy policy/tags
- 编写能精确指出缺失键的策略:
package tags
required := {"owner", "cost-center", "environment"}
deny[msg] {
rc := input.resource_changes[_]
rc.change.actions[_] != "delete"
tags := object.get(rc.change.after, "tags", {})
is_object(tags)
missing := required - {key | tags[key]}
count(missing) > 0
msg := sprintf("%s is missing tags: %v", [rc.address, missing])
}
deny[msg] {
rc := input.resource_changes[_]
rc.change.actions[_] != "delete"
not is_object(object.get(rc.change.after, "tags", {}))
msg := sprintf("%s has no tags block", [rc.address])
}
- 审计已经缺少成本标签的存量资源:
aws resourcegroupstaggingapi get-resources \
--query 'ResourceTagMappingList[?length(Tags[?Key==`cost-center`])==`0`].ResourceARN' \
--output text
- 在模块中提供安全的默认标签:
variable "tags" {
type = map(string)
default = {
owner = "checkout"
"cost-center" = "cc-1042"
environment = "prod"
}
}
验证
引入一个不带标签的资源后,conftest test 应以非零退出并输出资源地址与缺失键;补充标签后应通过。存量审计应能列出缺少 cost-center 的 ARN,按成本排序形成清理清单。最后确认账单控制台中对应的标签键已激活,否则即使标签齐全也不会出现在成本报告中。
注意事项
- 策略只覆盖 Terraform 管理的资源,控制台创建的资源需要单独审计。
- 只校验键存在会允许
cost-center: unknown扩散,应同时校验取值范围。 - 应基于 plan JSON 而不是 HCL 判断,因为变量与默认值在 plan 阶段才确定。
- 默认标签能降低摩擦,但不能放松门禁,错误默认值比构建失败更危险。
- 不支持标签的资源类型需要显式排除并记录原因。