AWS Security Group Rule冲突:cidr_blocks与source_security_group_id报错
Terraform AWS安全组规则冲突问题解决
问题场景
配置AWS安全组规则时,本地变量sg_rules中每条规则要么包含有效cidr_blocks且security_group_id为null,要么cidr_blocks为空列表且security_group_id有效,但在使用aws_security_group_rule资源的for_each批量创建规则时,触发了参数冲突错误。
本地变量sg_rules定义
sg_rules = { "testsg_1-ingress-1521-tcp-10.80.0.10/32" = { "cidr_blocks" = tolist(["10.80.0.10/32",]) "description" = "1521 tcp ingress" "from_port" = 1521 "protocol" = "tcp" "security_group_id" = tostring(null) "sg_name" = "testsg_1" "to_port" = 1521 "type" = "ingress" }, "testsg_2-ingress-1524-tcp-sg-23423439" = { "cidr_blocks" = tolist([]) "description" = "1524 tcp ingress" "from_port" = 1524 "protocol" = "tcp" "security_group_id" = "sg-23423439" "sg_name" = "testsg_2" "to_port" = 1524 "type" = "ingress" } }
原资源配置
resource "aws_security_group_rule" "tcp_cidr_blocks" { for_each = { for key, sg_rule in local.sg_rules : key => sg_rule } type = each.value.type from_port = each.value.from_port to_port = each.value.to_port cidr_blocks = each.value.cidr_blocks source_security_group_id = each.value.security_group_id protocol = each.value.protocol security_group_id = aws_security_group.security_groups.id }
触发的错误
Error: Conflicting configuration arguments with module.sg.aws_security_group_rule.tcp_cidr_blocks["testsg_2-ingress-1524-tcp-sg-23423439"], on sg/main.tf line 30, in resource "aws_security_group_rule" "tcp_cidr_blocks" : 30: source_security_group_id = each.value.security_group_id "security_group_id": conflicts with cidr_blocks
解决方法
Terraform的配置验证是静态的,只要同时声明cidr_blocks和source_security_group_id这两个冲突参数,哪怕其中一个值为空,也会触发冲突检查。必须确保每个规则实例只声明其中一个参数,以下两种方案均可解决:
方案一:拆分资源,分别处理两类规则
将CIDR类型和安全组类型的规则拆分为两个独立的aws_security_group_rule资源,通过for_each的条件过滤分别处理:
# 处理CIDR块规则 resource "aws_security_group_rule" "tcp_cidr_blocks" { for_each = { for key, sg_rule in local.sg_rules : key => sg_rule if length(sg_rule.cidr_blocks) > 0 } type = each.value.type from_port = each.value.from_port to_port = each.value.to_port cidr_blocks = each.value.cidr_blocks protocol = each.value.protocol security_group_id = aws_security_group.security_groups.id } # 处理源安全组规则 resource "aws_security_group_rule" "tcp_source_sg" { for_each = { for key, sg_rule in local.sg_rules : key => sg_rule if sg_rule.security_group_id != null } type = each.value.type from_port = each.value.from_port to_port = each.value.to_port source_security_group_id = each.value.security_group_id protocol = each.value.protocol security_group_id = aws_security_group.security_groups.id }
方案二:条件赋值,动态仅设置有效参数
在单个资源中通过条件判断,只在参数有有效值时才声明该参数:
resource "aws_security_group_rule" "tcp_rules" { for_each = local.sg_rules type = each.value.type from_port = each.value.from_port to_port = each.value.to_port protocol = each.value.protocol security_group_id = aws_security_group.security_groups.id # 仅当cidr_blocks非空时赋值 cidr_blocks = length(each.value.cidr_blocks) > 0 ? each.value.cidr_blocks : null # 仅当security_group_id非空时赋值 source_security_group_id = each.value.security_group_id != null ? each.value.security_group_id : null }
内容的提问来源于stack exchange,提问作者Abhishek Solanki
相关产品推荐
相关产品推荐

