使用Terraform aws_security_group动态块时遇参数错误求助
问题分析与解决
错误原因
你遇到的Unsupported argument: protocol错误,核心原因是:
aws_security_group资源的根级别protocol参数属于旧版语法,仅适用于不单独定义ingress/egress块的场景。- 当使用
dynamic "ingress"块批量生成入站规则时,协议配置必须放在每个ingress规则的content内部,根级别不再接受protocol参数。
另外你的代码还有两个潜在问题:
dynamic "ingress"的for_each遍历的是local.config_ports(包含Ports键的对象),正确应该遍历local.config_ports.Ports数组,否则无法直接访问Description/FromPort字段。aws_ec2_managed_prefix_list.pl-rules的for_each引用了local.rules_names,但你在locals里定义的是rule_name,存在拼写错误。
修正后的代码
修正aws_security_group资源
resource "aws_security_group" "using-pl" { name = "using-pl" vpc_id = aws_vpc.testing.id dynamic "ingress" { for_each = local.config_ports.Ports content { description = ingress.value.Description from_port = ingress.value.FromPort to_port = ingress.value.ToPort protocol = "tcp" # 将protocol移到ingress规则内部 # 如果需要指定源前缀列表,在这里添加: # prefix_list_ids = [for v in aws_ec2_managed_prefix_list.pl-rules : v.id] } } }
修正前缀列表的变量拼写错误
locals { config_ports = jsondecode(file("ports.json")) rule_names = keys(local.config_ports) # 修正变量名为rule_names ports_config = tomap(merge([ for rules, v in local.config_ports : { for i, ports in v : "${rules}${i}" => { fromport = ports.FromPort toport = ports.ToPort description = ports.Description } } ]...)) } resource "aws_ec2_managed_prefix_list" "pl-rules" { for_each = { for idx, rule_name in local.rule_names : rule_name => idx } # 引用正确的变量 name = "pl-${each.key}" address_family = "IPv4" max_entries = 7 }
补充说明
- 每个
ingress规则必须明确指定protocol,如果所有规则都是TCP,直接写在content块里即可;如果有不同协议,可以在JSON配置中新增Protocol字段,通过ingress.value.Protocol引用。 - 安全组根级别的
prefix_list_ids是安全组本身关联的前缀列表(用于流量过滤的补充),如果要把前缀列表作为入站规则的源,需要将其放到ingress的content块内。
内容的提问来源于stack exchange,提问作者surya
相关产品推荐
相关产品推荐

