如何在Terraform AWS安全组模块中集成前缀列表与CIDR规则?
在terraform-aws-modules/security-group/aws 5.1.0中同时使用CIDR与前缀列表Ingress规则的方案
核心结论
完全可以在同一个安全组模块实例中同时使用ingress_with_cidr_blocks和ingress_with_prefix_list_ids两种Ingress规则,二者不存在互斥关系。
错误原因解析
你遇到的错误是因为ingress_with_prefix_list_ids变量要求的是字符串映射(map of string)的列表,每个映射需要包含prefix_list_id、from_port、to_port、protocol等必填字段;而你直接传入了data.aws_ec2_managed_prefix_list.my-prefix-list这个数据源对象,不符合变量的类型要求。
正确配置示例
基础配置(单前缀列表规则)
首先获取目标前缀列表的数据源:
data "aws_ec2_managed_prefix_list" "my-prefix-list" { name = "自定义前缀列表名称" }
然后在模块调用中同时声明两种Ingress规则:
module "security_group" { for_each = var.security_groups source = "terraform-aws-modules/security-group/aws" version = "5.1.0" name = each.value.name description = each.value.description vpc_id = var.vpc_id # 原有CIDR格式的Ingress规则 ingress_with_cidr_blocks = each.value.ingress_cidrs # 前缀列表格式的Ingress规则(注意结构为map) ingress_with_prefix_list_ids = [ { prefix_list_id = data.aws_ec2_managed_prefix_list.my-prefix-list.id from_port = 443 to_port = 443 protocol = "tcp" description = "允许来自自定义前缀列表的HTTPS流量" } # 可添加更多前缀列表规则项 ] }
批量配置适配(配合for_each)
如果需要为不同安全组配置不同的前缀列表规则,可以在变量中扩展定义,再动态生成规则:
- 定义包含前缀列表规则的变量:
variable "security_groups" { type = map(object({ name = string description = string # CIDR规则配置 ingress_cidrs = list(object({ cidr_block = string from_port = number to_port = number protocol = string description = string })) # 前缀列表规则配置 ingress_prefix_lists = list(object({ prefix_list_name = string from_port = number to_port = number protocol = string description = string })) })) }
- 动态获取所有需要的前缀列表:
data "aws_ec2_managed_prefix_list" "sg_prefix_lists" { for_each = flatten([ for sg in var.security_groups : [ for pl in sg.ingress_prefix_lists : pl.prefix_list_name ] ]) name = each.key }
- 在模块中批量生成两种规则:
module "security_group" { for_each = var.security_groups source = "terraform-aws-modules/security-group/aws" version = "5.1.0" name = each.value.name description = each.value.description vpc_id = var.vpc_id ingress_with_cidr_blocks = each.value.ingress_cidrs ingress_with_prefix_list_ids = [ for pl in each.value.ingress_prefix_lists : { prefix_list_id = data.aws_ec2_managed_prefix_list.sg_prefix_lists[pl.prefix_list_name].id from_port = pl.from_port to_port = pl.to_port protocol = pl.protocol description = pl.description } ] }
内容的提问来源于stack exchange,提问作者Miloš Milutinov
相关产品推荐
相关产品推荐

