Files
homelab-opentofu/modules/01-networking/caddy-proxy/main.tf
2025-08-21 17:40:06 +10:00

128 lines
3.2 KiB
HCL

terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
}
}
locals {
container_name = var.container_name != "" ? var.container_name : "caddy-proxy"
image_tag = var.image_tag != "" ? var.image_tag : "latest"
// Filter services to only include those that should be published via reverse proxy
proxy_services = [
for service in var.service_definitions :
service if length(service.subdomains) > 0 && (service.publish_via == "reverse_proxy" || service.publish_via == "both")
]
// Transform service definitions into Caddyfile blocks
caddy_site_configs = flatten([
for service in local.proxy_services :
[
for subdomain in service.subdomains : {
site_address = "${subdomain}.${var.domain}"
endpoint = service.endpoint
service_name = service.name
tls_email = var.tls_email
has_custom_config = service.caddy_config != ""
custom_config = service.caddy_config
reverse_proxy_options = service.caddy_options
proxied = service.proxied
}
]
])
// Generate the main Caddyfile content
caddyfile_content = join("\n\n", [
for site in local.caddy_site_configs :
site.has_custom_config ?
// Use the custom Caddy config if provided
<<-EOT
${site.site_address} {
tls ${var.tls_email}
${site.custom_config}
}
EOT
:
// Otherwise use the standard reverse proxy config with options
<<-EOT
${site.site_address} {
tls ${var.tls_email}
reverse_proxy ${site.endpoint} {
${join("\n ", [
for key, value in site.reverse_proxy_options :
"${key} ${value}"
])}
}
}
EOT
])
}
// Create Caddyfile in the volume path
resource "local_file" "caddyfile" {
content = local.caddyfile_content
filename = "${var.volume_path}/caddy/Caddyfile"
}
module "dns_records" {
count = var.cloudflare_zone_id != "" ? 1 : 0
source = "../../10-services-generic/cloudflare-dns"
zone_id = var.cloudflare_zone_id
dns_records = {
for site in local.caddy_site_configs : site.site_address => {
name = site.site_address
value = var.external_ip
type = "A"
proxied = site.proxied
ttl = 1
}
}
}
module "caddy" {
source = "../../10-services-generic/docker-service"
container_name = local.container_name
image = "caddy"
tag = local.image_tag
volumes = [
{
host_path = "${var.volume_path}/caddy/data"
container_path = "/data"
read_only = false
},
{
host_path = "${var.volume_path}/caddy/config"
container_path = "/config"
read_only = false
},
{
host_path = "${var.volume_path}/caddy/Caddyfile"
container_path = "/etc/caddy/Caddyfile"
read_only = true
}
]
ports = [
{
external = "80"
internal = "80"
protocol = "tcp"
},
{
external = "443"
internal = "443"
protocol = "tcp"
}
]
monitoring = var.monitoring
networks = var.networks
}