diff --git a/README.md b/README.md index a95a43c..dd87041 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ No modules. | [cloudflare_zero_trust_access_application.grafana_alerts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.k3s](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.mcp_gateway](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | -| [cloudflare_zero_trust_access_application.mcp_gateway_backends](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | +| [cloudflare_zero_trust_access_application.mcp_gateway_backend](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.warp](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_group.admins](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_group) | resource | | [cloudflare_zero_trust_access_identity_provider.github](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_identity_provider) | resource | diff --git a/cf-access-mcp.tf b/cf-access-mcp.tf index 81bb0ad..aea292b 100644 --- a/cf-access-mcp.tf +++ b/cf-access-mcp.tf @@ -43,15 +43,16 @@ resource "cloudflare_zero_trust_access_application" "mcp_gateway" { ] } -# Per-backend MCP endpoints (.mcp.makeitwork.cloud) terminate on the -# same toolhive proxyrunners behind the same tunnel. Wildcard application so -# each integration gets its own FQDN without a new Access app per backend; -# same service-token + admins policies as the aggregate gateway above. -resource "cloudflare_zero_trust_access_application" "mcp_gateway_backends" { +# Per-backend MCP endpoints (mcp-.makeitwork.cloud) terminate on the +# same toolhive proxyrunners behind the same tunnel. One application per FQDN: +# Access domains cannot wildcard a name prefix, and first-level names are +# required anyway because Universal SSL only covers one subdomain level. +resource "cloudflare_zero_trust_access_application" "mcp_gateway_backend" { + for_each = toset(local.mcp_backends) account_id = local.account_id - name = "MCP Gateway Backends" + name = "MCP ${each.key}" type = "self_hosted" - domain = "*.mcp.makeitwork.cloud" + domain = "mcp-${each.key}.makeitwork.cloud" session_duration = "24h" allowed_idps = [ diff --git a/cf-tunnels.tf b/cf-tunnels.tf index 2a5c299..78afc7c 100644 --- a/cf-tunnels.tf +++ b/cf-tunnels.tf @@ -16,28 +16,35 @@ data "cloudflare_zero_trust_tunnel_cloudflared" "cluster_apps" { # kustomize-cluster picks up traffic for each FQDN; this CNAME just tells # Cloudflare's edge which tunnel to route requests through. locals { - cluster_apps_hostnames = [ - "api", - "argocd", - "forgejo", - "grafana", - "k3s", - "mcp", - # Per-backend MCP endpoints (toolhive proxyrunners); the aggregate - # VirtualMCPServer stays at the bare "mcp" hostname above. - "apify.mcp", - "argocd-makeitwork.mcp", - "aws-docs.mcp", - "context7.mcp", - "github.mcp", - "grafana-makeitwork.mcp", - "kubernetes.mcp", - "parallel-search.mcp", - "terraform-docs.mcp", - "opencode", - "status", - "alertmanager", + # Per-backend MCP endpoints (toolhive proxyrunners); the aggregate + # VirtualMCPServer stays at the bare "mcp" hostname. First-level names are + # required: Cloudflare Universal SSL only covers *.makeitwork.cloud, so + # .mcp.makeitwork.cloud cannot present a certificate. + mcp_backends = [ + "apify", + "argocd-makeitwork", + "aws-docs", + "context7", + "github", + "grafana-makeitwork", + "kubernetes", + "parallel-search", + "terraform-docs", ] + cluster_apps_hostnames = concat( + [ + "api", + "argocd", + "forgejo", + "grafana", + "k3s", + "mcp", + "opencode", + "status", + "alertmanager", + ], + [for backend in local.mcp_backends : "mcp-${backend}"], + ) } resource "cloudflare_dns_record" "cluster_apps" {