问题描述
在使用 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
函数来实现类似的验证逻辑。验证成功将有助于确保配置文件中的变量满足预期条件,从而提高系统的稳定性和可靠性。