You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Terraform中实现两个列表笛卡尔积及合并列表创建网络ACL可行吗?

Absolutely! Terraform provides flexible functions to handle both merging lists for your network ACL configurations and generating Cartesian products of lists. Let’s walk through both scenarios with practical examples.

Merging Lists to Create Network ACLs

This is totally feasible, and it’s a common pattern when you want to combine base ACL rules with environment-specific or additional rules. The concat() function is your go-to here—it takes multiple lists and appends them into a single list.

Here’s a concrete example:

# Define your base ACL rules (e.g., default allow/deny rules)
variable "base_ingress_rules" {
  type = list(object({
    protocol   = string
    rule_no    = number
    action     = string
    cidr_block = string
    from_port  = number
    to_port    = number
  }))
  default = [
    {
      protocol   = "tcp"
      rule_no    = 100
      action     = "allow"
      cidr_block = "0.0.0.0/0"
      from_port  = 80
      to_port    = 80
    }
  ]
}

# Define additional rules you want to add
variable "extra_ingress_rules" {
  type = list(object({
    protocol   = string
    rule_no    = number
    action     = string
    cidr_block = string
    from_port  = number
    to_port    = number
  }))
  default = [
    {
      protocol   = "tcp"
      rule_no    = 110
      action     = "allow"
      cidr_block = "192.168.1.0/24"
      from_port  = 22
      to_port    = 22
    }
  ]
}

# Combine the lists and create the network ACL
resource "aws_network_acl" "main" {
  vpc_id = aws_vpc.main.id

  ingress = concat(var.base_ingress_rules, var.extra_ingress_rules)
  egress  = concat(var.base_egress_rules, var.extra_egress_rules) # Repeat for egress if needed
}

Just make sure your rule numbers don’t overlap—Terraform will throw an error if duplicate rule numbers exist in the same ACL. Plan your rule number ranges ahead (e.g., base rules 100-199, extra rules 200-299) to avoid conflicts.

Generating Cartesian Products

To create a Cartesian product of two lists (all possible combinations of elements from each list), use Terraform’s setproduct() function. It accepts multiple lists/sets and returns a list of lists, where each sublist is a combination of one element from each input list.

Example 1: Simple Value Lists

Say you want to create ACL rules for every combination of subnets and allowed ports:

variable "subnet_cidrs" {
  type    = list(string)
  default = ["10.0.1.0/24", "10.0.2.0/24"]
}

variable "allowed_ports" {
  type    = list(number)
  default = [80, 443, 22]
}

locals {
  # Generate all subnet-port combinations
  acl_combinations = setproduct(var.subnet_cidrs, var.allowed_ports)
}

# Create an ACL rule for each combination
resource "aws_network_acl_rule" "allowed_traffic" {
  count             = length(local.acl_combinations)
  network_acl_id    = aws_network_acl.main.id
  rule_number       = 100 + count.index
  protocol          = "tcp"
  rule_action       = "allow"
  cidr_block        = local.acl_combinations[count.index][0]
  from_port         = local.acl_combinations[count.index][1]
  to_port           = local.acl_combinations[count.index][1]
  egress            = false
}

This will create 6 rules total (2 subnets × 3 ports).

Example 2: Complex Object Lists

If you’re working with lists of objects, you can combine setproduct() with merge() to create combined objects:

variable "source_cidrs" {
  type = list(object({
    cidr_block = string
    description = string
  }))
  default = [
    { cidr_block = "10.0.1.0/24", description = "Internal subnet" },
    { cidr_block = "0.0.0.0/0", description = "Internet" }
  ]
}

variable "dest_ports" {
  type = list(object({
    port = number
    protocol = string
  }))
  default = [
    { port = 80, protocol = "tcp" },
    { port = 443, protocol = "tcp" }
  ]
}

locals {
  combined_rules = [
    for combo in setproduct(var.source_cidrs, var.dest_ports) : merge(
      combo[0],
      combo[1],
      { action = "allow", rule_prefix = 200 }
    )
  ]
}

The local.combined_rules will be a list of 4 objects, each merging the source CIDR details, port/protocol, and the additional action/rule_prefix fields.

Note on Duplicates

setproduct() automatically removes duplicate combinations. If you need to preserve duplicates (e.g., if your input lists have duplicate elements and you want all combinations including those), use nested for loops with flatten() instead:

locals {
  cartesian_with_duplicates = flatten([
    for source in var.source_cidrs : [
      for port in var.dest_ports : {
        source = source
        port = port
      }
    ]
  ])
}

内容的提问来源于stack exchange,提问作者grbonk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:31:14