如何在Terraform中为Cloudflare Tunnel配置对应主机的Ingress规则?
解决Cloudflare Tunnel Ingress规则关联错误的问题
1. 先把CSV数据按隧道分组
首先读取你的CSV文件,用Terraform的groupby函数把主机条目按隧道名称/ID归类,确保每个隧道只对应自己的主机:
locals { # 读取CSV文件,替换成你的文件路径 tunnel_hosts = csvdecode(file("${path.module}/tunnels_hosts.csv")) # 按隧道名称分组,得到每个隧道对应的主机列表 tunnels_grouped = groupby(local.tunnel_hosts, "tunnel_name") }
假设你的CSV结构是这样的(可根据实际调整字段名):
tunnel_name,hostname,service tunnel-prod,app1.example.com,http://localhost:8080 tunnel-prod,app2.example.com,http://localhost:8081 tunnel-staging,stage-app.example.com,http://localhost:8080
2. 创建Cloudflare Tunnel(如果还没创建)
如果你的隧道还没定义,用for_each遍历分组后的隧道名称来创建:
resource "cloudflare_tunnel" "main" { for_each = keys(local.tunnels_grouped) account_id = var.cloudflare_account_id name = each.key }
3. 生成对应隧道的专属Ingress规则
在tunnel_config里,遍历分组后的隧道数据,只为当前隧道生成关联的Ingress规则:
resource "cloudflare_tunnel_config" "main" { for_each = local.tunnels_grouped account_id = var.cloudflare_account_id tunnel_id = cloudflare_tunnel.main[each.key].id config { ingress_rule { # 动态生成当前隧道的所有主机Ingress规则 dynamic "ingress" { for_each = each.value content { hostname = ingress.value.hostname service = ingress.value.service } } # 可选:添加默认规则,匹配不到主机时返回404 ingress { service = "http_status:404" } } } }
核心要点
- 用
groupby分组是关键,直接把CSV里的主机和隧道绑定,从根源上解决了所有隧道共享Ingress规则的问题。 dynamic "ingress"块会自动遍历当前隧道的主机列表,生成对应规则,不用手动重复写代码。- 别再用
depends_on了,for_each场景下它根本起不到预期作用。直接让tunnel_config引用对应隧道的ID,Terraform会自动处理资源创建顺序,比depends_on靠谱得多。
内容的提问来源于stack exchange,提问作者user1782878
相关产品推荐
相关产品推荐

