Terraform 变量类型验证与集合类型

35次阅读
没有评论

问题描述

在使用 Terraform 时遇到了一个关于验证变量类型的问题。他想知道是否可以验证一个变量的类型是否为 list(string)。他提供了一个示例以及他的验证代码,但在尝试执行时遇到了错误。

以下是用户提供的示例代码:
main.tf

name            = "tf-prd-sg-foo"
image_id        = "ami-00e788542ee66c64f"
instance_type   = "m5.xlarge"
security_groups = ["sg-000000", "sg-00000000"]

vars.tf

variable "security_groups"  {
    type        = list(string)
    default     = []
    description = "(Optional) A list of associated security group IDs."
    validation {
      condition = can(regex("^sg-", var.security_groups))
      error_message = "The Security Groups need to start with \"sg-\"."
    }
}

但在执行时,他遇到了以下错误:

[terragrunt] 2021/01/05 17:12:10 Running command: terraform planError: Invalid value for variable  on vars.tf line 21:  21: variable "security_groups"  {The Security Groups need to start with "sg-".This was checked by the validation rule at vars.tf:26,5-15.[terragrunt] 2021/01/05 17:12:12 Hit multiple errors:exit status 1

解决方案

请注意以下操作可能存在版本差异,执行前务必备份。

方案1:使用 alltrue 函数和 for 表达式(适用于 Terraform v0.14 及更新版本)

在 Terraform 中,当对集合类型的输入变量进行验证时,通常我们希望对集合中的每个值进行测试,而不仅仅对整个集合进行测试。

你可以使用 Terraform v0.14 或更新版本中引入的 alltrue 函数结合 for 表达式来实现类似的条件验证,如下所示:

validation {
  condition = alltrue([
    for id in var.security_groups : can(regex("^sg-", id))
  ])
  error_message = "All security group IDs must start with \"sg-\"."
}

在上述示例中,我们使用 for 表达式遍历 var.security_groups 中的每个值,然后使用 can(regex("^sg-", id)) 验证表达式判断是否满足条件。最终,alltrue 函数将检查所有验证结果是否都为 true,从而决定整体验证结果。

方案2:使用 if 子句和 length 函数(适用于 Terraform v0.13)

如果你正在使用 Terraform v0.13,那么你可能没有可用的 alltrue 函数,但可以使用类似的方法实现类似的验证。

validation {
  condition = length([
    for id in var.security_groups : id
    if !can(regex("^sg-", id))
  ]) == 0
  error_message = "All security group IDs must start with \"sg-\"."
}

在这个示例中,我们使用 if 子句和 ! 运算符将验证表达式取反,从而得到验证不通过的结果。然后,我们使用 length 函数来检查经过过滤后的列表是否为空,以决定整体验证结果。

总结

当验证集合类型的输入变量时,我们需要逐个验证集合中的每个值,而不仅仅是验证集合本身。根据 Terraform 的版本不同,你可以选择使用 alltrue 函数和 for 表达式,或者使用 if 子句和 length 函数来实现类似的验证逻辑。验证成功将有助于确保配置文件中的变量满足预期条件,从而提高系统的稳定性和可靠性。

正文完