You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform变量验证无理由导致计划失败,求排查错误原因

问题描述

我有一个Terraform模块,其policy_statements变量配置了如下验证规则:

variable "policy_statements" {
  description = "要创建的策略语句"
  type = map(object({
    path         = string
    capabilities = set(string)
  }))

validation {
    condition = alltrue([
      for stmt in var.policy_statements :
      contains(["create", "read", "update", "patch", "delete", "list"], stmt.capabilities)
    ])
    error_message = "capabilities的有效值为(\"create\", \"read\", \"update\", \"patch\", \"delete\", \"list\")."
  }

我在另一个Terraform模块中调用该模块:

module "policies" {
  source = "../../../../path/to"

  for_each = var.policies

  policy_statements = each.value

}

外层模块中policies变量声明为:

variable "policies" {
  description = "要创建的策略语句"
  type           = map(any)
}

执行时出现错误:

│ Error: Invalid value for variable
│
│   on main.tf line 38, in module "policies":
│   38:   policy_statements = each.value
│     ├────────────────
│     │ var.policy_statements is map of object with 2 elements
│
│ Valid values for capabilities are ("create", "read", "update", "patch",
│ "delete", "list").
│
│ This was checked by the validation rule at
│ ../../../../modules-terraform/vault/policies/variables.tf:12,3-13.

外层模块通过terragrunt.hcl读取policies变量:

locals {
  policies = yamldecode(file("config.yaml"))
}

inputs = {
  policies = local.policies
}

对应的config.yaml内容为:

policies:
  policy-test-1:
    capabilities:
      - read
      - create
    path: /foo/lala
  policy-test-2:
    capabilities:
      - update
      - delete
    path: /foo/lala

移除验证规则后计划就能成功执行,请问我的验证规则哪里出错了?

问题根源与解决方法

你的验证规则逻辑错误:stmt.capabilities是集合(set)类型,但你用contains函数直接检查这个集合是否存在于字符串列表中——列表里的元素是单个字符串,和集合类型不匹配,导致验证永远失败。

正确逻辑应该是:遍历每个策略语句的capabilities集合中的每一个元素,确保所有元素都属于允许的有效值列表。

修改后的验证规则如下:

validation {
    condition = alltrue([
      for stmt in var.policy_statements :
      alltrue([
        for cap in stmt.capabilities :
        contains(["create", "read", "update", "patch", "delete", "list"], cap)
      ])
    ])
    error_message = "capabilities的有效值为(\"create\", \"read\", \"update\", \"patch\", \"delete\", \"list\")."
  }

额外优化建议

  1. 外层模块的policies变量使用map(any)会丢失类型约束,建议改成和内层模块一致的类型定义,提前发现配置错误:
variable "policies" {
  description = "要创建的策略语句"
  type = map(object({
    path         = string
    capabilities = set(string)
  }))
}
  1. yamldecode读取YAML列表时会得到Terraform的list类型,虽然Terraform会自动转成set,但如果需要显式控制,可在调用模块时转换:
policy_statements = {
  path         = each.value.path
  capabilities = toset(each.value.capabilities)
}

内容的提问来源于stack exchange,提问作者pkaramol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:31:36