Terraform用对象列表做for_each创建AWS安全组规则报错如何解决?
问题原因
Terraform中for_each参数仅支持传入map类型或字符串集合类型,你传入的local.distinct_rule_list是对象列表类型,不符合参数要求,因此触发报错。
解决方案(推荐)
将对象列表转换为带唯一标识key的map类型,再传入for_each使用。该方案的优势是资源实例的唯一标识由自定义key决定,不会因为列表顺序调整、中间插入/删除元素触发不必要的资源重建。
修改后的资源代码如下:
resource "aws_security_group_rule" "dh_ingress_sg_rule" { # 遍历对象列表生成带唯一key的map for_each = { for rule in local.distinct_rule_list : # 拼接客户名+子网段作为唯一key,避免重复客户名导致key冲突 "${rule.customer_name}-${join("-", rule.rightsubnet)}" => rule } type = "ingress" from_port = 8000 to_port = 8080 protocol = "tcp" cidr_blocks = each.value.rightsubnet description = each.value.customer_name security_group_id = aws_security_group.sgtest.id }
备选方案(不推荐)
如果你的列表结构固定、不会调整顺序/插入元素,也可以使用count参数遍历列表,代码如下:
resource "aws_security_group_rule" "dh_ingress_sg_rule" { count = length(local.distinct_rule_list) type = "ingress" from_port = 8000 to_port = 8080 protocol = "tcp" cidr_blocks = local.distinct_rule_list[count.index].rightsubnet description = local.distinct_rule_list[count.index].customer_name security_group_id = aws_security_group.sgtest.id }
该方案的缺陷是列表顺序变更会导致Terraform误判资源实例需要重建,生产环境优先选择for_each转map的方案。
内容的提问来源于stack exchange,提问作者Jason Frazee
相关产品推荐
相关产品推荐

