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

如何用Terraform实现Google云端口段防火墙?复用AWS配置逻辑

问题:Terraform实现Google云防火墙端口规则的DRY方案

我已经通过AWS的from_port/to_port功能创建了防火墙(安全组),示例配置如下:

variable "list_port" {
  type = "list"
  default = [
    "5000-5100",
    "6000-6100",
    "7000-7100",
  ]
}
resource "aws_security_group" "test" {
  name = "test"
}
resource "aws_security_group_rule" "test" {
  count             = "${length(var.list_port)}"
  type              = "ingress"
  from_port         = "${ element(split("-", element(var.list_port, count.index)), 0) }"
  to_port           = "${ element(split("-", element(var.list_port, count.index)), 1) }"
  protocol          = "TCP"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = "${aws_security_group.test.id}"
}

现在尝试用Terraform实现Google云的相同需求,但发现Google云没有类似的from_port/to_port配置选项。我希望遵循DRY原则,避免重复配置端口,且需要适配包含待开放端口变量的Terraform模块,不想采用如下冗余写法:

resource "google_compute_firewall" "firewall" {
  name        = "test"
  direction   = "INGRESS"
  allow {
    protocol = "tcp"
    ports    = [5000, 5100]
  }
  allow {
    protocol = "tcp"
    ports    = [6000, 6100]
  }
  allow {
    protocol = "tcp"
    ports    = [7000, 7100]
  }
}

请问是否有更优的实现方案?谢谢!


最优实现方案

当然有!我们可以利用Terraform的动态块和字符串处理函数,完美匹配你的需求,既遵循DRY原则,又能适配现有端口变量。

基础实现代码

variable "list_port" {
  type        = list(string)
  description = "List of port ranges in 'start-end' format"
  default = [
    "5000-5100",
    "6000-6100",
    "7000-7100",
  ]
}

resource "google_compute_firewall" "firewall" {
  name          = "test"
  direction     = "INGRESS"
  network       = "default" # 替换为你的实际网络名称
  source_ranges = ["0.0.0.0/0"]

  # 动态生成每个端口范围对应的allow块
  dynamic "allow" {
    for_each = var.list_port
    content {
      protocol = "tcp"
      ports    = split("-", allow.value)
    }
  }
}

方案细节说明

  1. 动态块dynamic "allow":通过for_each遍历你的端口范围列表,为每个条目自动生成一个allow块,彻底消除重复代码。
  2. 端口范围处理:用split("-", allow.value)直接将"start-end"格式的字符串拆分成端口列表,和你AWS配置中的逻辑完全对齐。
  3. 模块友好性:整个逻辑完全基于var.list_port变量,后续添加或修改端口范围只需要调整变量值,不需要修改资源结构,非常适合封装成可复用模块。

扩展适配:支持单个端口

如果你的端口列表可能包含单个端口(比如"80"),可以优化逻辑兼容这种场景:

dynamic "allow" {
  for_each = var.list_port
  content {
    protocol = "tcp"
    ports    = contains(allow.value, "-") ? split("-", allow.value) : [allow.value]
  }
}

这样无论是单个端口还是端口范围,都能被正确识别和配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:11:27