Files
homelab/terraform/edge/cloudflare.tf
T
pi eb83aa6290 refactor(edge,iam): apply best practices to relay and Zitadel config
- edge: extract VPC/subnet/bandwidth/disk/DNS/Caddy settings into variables
- edge: add Caddyfile template with SSE-safe flush_interval -1 and security headers
- edge: add WireGuard NAT masquerade so homelab peer accepts forwarded client IPs
- edge: mark user_data sensitive and add prevent_destroy to the relay instance
- edge: validate relay_admin_cidr and Cloudflare hostnames
- edge: parameterise Cloudflare TTL/proxied and enforce proxied tunnel CNAMEs
- iam: fix PDB key to chart-supported pdb and remove unsupported extraVolumes
- iam: keep login hardened; drop unsupported login PDB
2026-10-25 18:03:55 -07:00

52 lines
1.7 KiB
Terraform

# Cloudflare side of the edge.
#
# The tunnel itself is remotely managed today: its token lives in
# k8s/apps/cloudflared and the public hostnames are configured in the Zero
# Trust dashboard. Terraform can own the DNS records without owning the tunnel,
# which is the safe half: a record change is reversible, a tunnel config rewrite
# removes every hostname the plan does not list.
locals {
# CNAME target of every remotely-managed tunnel.
tunnel_target = "${var.tunnel_id}.cfargotunnel.com"
}
resource "cloudflare_dns_record" "tunnel" {
for_each = toset(var.cloudflare_tunnel_hostnames)
zone_id = var.cloudflare_zone_id
name = each.value
type = "CNAME"
content = local.tunnel_target
proxied = var.cloudflare_dns_proxied
ttl = var.cloudflare_dns_ttl
comment = "cloudflared tunnel; managed by terraform/edge"
# A proxied CNAME must point at the tunnel target. A CNAME to any other
# hostname breaks the tunnel mapping.
lifecycle {
precondition {
condition = var.cloudflare_dns_proxied
error_message = "Tunnel CNAMEs must be proxied; an unproxied record bypasses the tunnel."
}
}
}
# Optional: take the tunnel configuration into Terraform. Off by default.
# Applying it REPLACES the whole ingress list. Import first:
# terraform import cloudflare_zero_trust_tunnel_cloudflared_config.this \
# <account_id>/<tunnel_id>
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "this" {
count = var.manage_tunnel_config ? 1 : 0
account_id = var.cloudflare_account_id
tunnel_id = var.tunnel_id
config = {
ingress = concat(
[for host, service in var.tunnel_ingress : { hostname = host, service = service }],
[{ service = "http_status:404" }],
)
}
}