#========================================================== # Local Variables #========================================================== locals { # Certificate data - gateway_ca_certificate is defined in ssh-ca-management.tf # WARP connector tokens azure_warp_connector_token = jsondecode(data.http.cloudflare_warp_connector_token_azure.response_body).result gcp_warp_connector_token = jsondecode(data.http.cloudflare_warp_connector_token_gcp.response_body).result # Tunnel configurations tunnels = { gcp_infrastructure = { name = var.cloudflare_tunnel_name_gcp routes = [ { comment = "Route making GCP subnet available in the Cloudflare network" network = var.gcp_infra_cidr } ] public_hostnames = [ { hostname = var.cloudflare_subdomain_web service = "http://localhost:${var.cloudflare_intranet_app_port}" aud_tag = "gcp_intranet_web_app" }, { hostname = var.cloudflare_subdomain_web_sensitive service = "http://localhost:${var.cloudflare_competition_app_port}" aud_tag = "competition_web_app" } ] } gcp_windows_rdp = { name = var.cloudflare_windows_rdp_tunnel_name_gcp routes = [ { comment = "Route making GCP Windows RDP subnet available in the Cloudflare network" network = var.gcp_windows_rdp_cidr } ] } aws_browser_rendering = { name = var.cloudflare_tunnel_name_aws routes = [ { comment = "Route making AWS private subnet available in the Cloudflare network" network = var.aws_private_cidr } ] } } # HTTP request headers for API calls cloudflare_api_headers = { "Authorization" = "Bearer ${var.cloudflare_api_token}" "Content-Type" = "application/json" } } #========================================================== # Data Sources #========================================================== data "http" "cloudflare_warp_connector_token_azure" { url = "https://api.cloudflare.com/client/v4/accounts/${local.cloudflare_account_id}/warp_connector/${var.cloudflare_tunnel_warp_connector_azure_id}/token" request_headers = local.cloudflare_api_headers } data "http" "cloudflare_warp_connector_token_gcp" { url = "https://api.cloudflare.com/client/v4/accounts/${local.cloudflare_account_id}/warp_connector/${var.cloudflare_tunnel_warp_connector_gcp_id}/token" request_headers = local.cloudflare_api_headers } #========================================================== # Cloudflare Tunnels #========================================================== resource "cloudflare_zero_trust_tunnel_cloudflared" "tunnels" { for_each = local.tunnels account_id = local.cloudflare_account_id name = each.value.name config_src = "cloudflare" } #========================================================== # Tunnel Tokens #========================================================== data "cloudflare_zero_trust_tunnel_cloudflared_token" "tunnel_tokens" { for_each = local.tunnels account_id = local.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.tunnels[each.key].id } #========================================================== # Private Network Routes #========================================================== resource "cloudflare_zero_trust_tunnel_cloudflared_route" "routes" { for_each = { for route_key, route in flatten([ for tunnel_key, tunnel in local.tunnels : [ for route_idx, route in tunnel.routes : { key = "${tunnel_key}_${route_idx}" tunnel = tunnel_key comment = route.comment network = route.network } ] ]) : route.key => route } account_id = local.cloudflare_account_id comment = each.value.comment tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.tunnels[each.value.tunnel].id network = each.value.network } #========================================================== # Public Hostname Configurations - GCP Only (no AWS IPs dependency) #========================================================== resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gcp_public_hostname" { account_id = local.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.tunnels["gcp_infrastructure"].id config = { ingress = [ { hostname = var.cloudflare_subdomain_web service = "http://localhost:8080" origin_request = { access = { aud_tag = [cloudflare_zero_trust_access_application.cloudflare_app_web_intranet.aud] required = true team_name = var.cloudflare_team_name } } }, { hostname = var.cloudflare_subdomain_web_sensitive service = "http://localhost:8181" origin_request = { access = { aud_tag = [cloudflare_zero_trust_access_application.cloudflare_app_web_competition.aud] required = true team_name = var.cloudflare_team_name } } }, { service = "http_status:404" } ] } } #========================================================== # AWS Public Hostname Configuration (requires AWS instances) #========================================================== resource "cloudflare_zero_trust_tunnel_cloudflared_config" "aws_public_hostname" { account_id = local.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.tunnels["aws_browser_rendering"].id config = { ingress = [ { hostname = var.cloudflare_subdomain_ssh service = "ssh://10.12.13.14:22" origin_request = { access = { aud_tag = [cloudflare_zero_trust_access_application.cloudflare_app_ssh_browser.aud] required = true team_name = var.cloudflare_team_name } } }, { hostname = var.cloudflare_subdomain_vnc service = "tcp://10.15.16.17:5901" origin_request = { access = { aud_tag = [cloudflare_zero_trust_access_application.cloudflare_app_vnc_browser.aud] required = true team_name = var.cloudflare_team_name } } }, { service = "http_status:404" } ] } }