非实验特性下Terraform基于对象列表变量实现条件动态块的配置及identity_ids必填错误解决
你遇到的问题核心在于:Terraform的object类型默认所有属性都是必填项,哪怕你在变量默认值里给了null,当你显式传入变量值时,每个object元素都必须包含所有定义的属性。你之前的默认值只在完全不传入identity变量时生效,而当你传入了部分属性的对象,Terraform就会校验完整性,所以报错说identity_ids是必填的。
下面给你两种可行的解决方案:
方案1:使用可选属性(推荐)
从Terraform 0.14版本开始,支持用optional()函数标记object的属性为可选,并且可以指定默认值。修改你的variables.tf如下:
variable "identity" { type = list(object({ type = string identity_ids = optional(list(string), null) })) default = [] # 改为空列表,方便完全不需要identity块的场景 }
这样修改后,当你调用模块时,可以只传入type属性,identity_ids会自动使用默认的null值,完全符合你的需求。同时空列表的默认值也更合理——如果用户不需要配置identity,直接不用传这个变量即可,dynamic块会因为for_each是空列表而不生成。
方案2:显式传入null值(兼容旧版本)
如果你因为Terraform版本限制不能用optional(),那只能在调用模块时显式给identity_ids赋值为null:
module "cognitive_account" { source = "../modules/cognitive-account" name = "name" location = "Australia East" resource_group_name = module.rg.name kind = "TextAnalytics" sku_name = "S" custom_subdomain_name = "unique-name" identity = [{ type = "SystemAssigned" identity_ids = null }] }
这种方法虽然能解决错误,但不够简洁,每次都要手动写identity_ids = null,所以更推荐方案1。
另外补充一点:你原来的默认值是[{type = null, identity_ids = null}],这意味着如果用户不传入identity变量,会自动生成一个空的identity块,这可能不符合预期(比如很多资源不需要identity时应该完全不配置这个块),所以改成default = []更合适,这样dynamic块不会生成任何内容。
内容的提问来源于stack exchange,提问作者philthy

