Skip to content

Commit b1e70f2

Browse files
committed
feat: add declarative tunnel management
- Add cf-tunnels.tf with 5 tunnels (argocd, grafana, uptime-kuma, awx, warp-connector) - Add 4 DNS CNAME records pointing to tunnel endpoints - Add WARP private network route (192.168.1.0/24) via SOPS - Import all existing resources into state
1 parent 8306854 commit b1e70f2

5 files changed

Lines changed: 132 additions & 18 deletions

File tree

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,31 @@ No modules.
2222

2323
| Name | Type |
2424
|------|------|
25+
| [cloudflare_dns_record.ansible_tunnel](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
2526
| [cloudflare_dns_record.api](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
2627
| [cloudflare_dns_record.apps](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
2728
| [cloudflare_dns_record.apps_wildcard](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
29+
| [cloudflare_dns_record.argocd_tunnel](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
30+
| [cloudflare_dns_record.grafana_tunnel](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
2831
| [cloudflare_dns_record.mx_primary](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
2932
| [cloudflare_dns_record.mx_secondary](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3033
| [cloudflare_dns_record.onion](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3134
| [cloudflare_dns_record.openshift_image_registry](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3235
| [cloudflare_dns_record.root](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3336
| [cloudflare_dns_record.spf](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
37+
| [cloudflare_dns_record.status_tunnel](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3438
| [cloudflare_dns_record.www](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/dns_record) | resource |
3539
| [cloudflare_ruleset.cache_rules](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) | resource |
3640
| [cloudflare_zero_trust_access_application.warp](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource |
3741
| [cloudflare_zero_trust_access_group.admins](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_group) | resource |
3842
| [cloudflare_zero_trust_access_identity_provider.github](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_identity_provider) | resource |
3943
| [cloudflare_zero_trust_organization.main](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_organization) | resource |
44+
| [cloudflare_zero_trust_tunnel_cloudflared.argocd](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource |
45+
| [cloudflare_zero_trust_tunnel_cloudflared.awx](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource |
46+
| [cloudflare_zero_trust_tunnel_cloudflared.grafana](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource |
47+
| [cloudflare_zero_trust_tunnel_cloudflared.uptime_kuma](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource |
48+
| [cloudflare_zero_trust_tunnel_cloudflared.warp](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) | resource |
49+
| [cloudflare_zero_trust_tunnel_cloudflared_route.private_network](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared_route) | resource |
4050
| [cloudflare_zone_setting.brotli](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource |
4151
| [cloudflare_zone_setting.browser_cache_ttl](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource |
4252
| [cloudflare_zone_setting.browser_check](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_setting) | resource |
@@ -55,5 +65,7 @@ No inputs.
5565

5666
## Outputs
5767

58-
No outputs.
68+
| Name | Description |
69+
|------|-------------|
70+
| <a name="output_tunnel_ids"></a> [tunnel\_ids](#output\_tunnel\_ids) | Cloudflare Tunnel IDs for reference in kustomize-cluster ConfigMaps |
5971
<!-- END_TF_DOCS -->

cf-tunnels.tf

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Cloudflare Tunnels for OpenShift workloads
2+
# Tunnels connect cloudflared pods to Cloudflare edge network
3+
#
4+
# Tunnel credentials are managed separately in kustomize-cluster via SOPS/KSOPS.
5+
6+
# =============================================================================
7+
# HTTP Tunnels (ingress-based)
8+
# =============================================================================
9+
10+
# ArgoCD tunnel
11+
resource "cloudflare_zero_trust_tunnel_cloudflared" "argocd" {
12+
account_id = local.account_id
13+
name = "argocd"
14+
}
15+
16+
resource "cloudflare_dns_record" "argocd_tunnel" {
17+
zone_id = local.zone_id
18+
type = "CNAME"
19+
name = "argocd"
20+
content = "${cloudflare_zero_trust_tunnel_cloudflared.argocd.id}.cfargotunnel.com"
21+
proxied = true
22+
ttl = 1
23+
}
24+
25+
# Grafana tunnel
26+
resource "cloudflare_zero_trust_tunnel_cloudflared" "grafana" {
27+
account_id = local.account_id
28+
name = "grafana"
29+
}
30+
31+
resource "cloudflare_dns_record" "grafana_tunnel" {
32+
zone_id = local.zone_id
33+
type = "CNAME"
34+
name = "grafana"
35+
content = "${cloudflare_zero_trust_tunnel_cloudflared.grafana.id}.cfargotunnel.com"
36+
proxied = true
37+
ttl = 1
38+
}
39+
40+
# Uptime Kuma tunnel (status.makeitwork.cloud)
41+
resource "cloudflare_zero_trust_tunnel_cloudflared" "uptime_kuma" {
42+
account_id = local.account_id
43+
name = "uptime-kuma"
44+
}
45+
46+
resource "cloudflare_dns_record" "status_tunnel" {
47+
zone_id = local.zone_id
48+
type = "CNAME"
49+
name = "status"
50+
content = "${cloudflare_zero_trust_tunnel_cloudflared.uptime_kuma.id}.cfargotunnel.com"
51+
proxied = true
52+
ttl = 1
53+
}
54+
55+
# AWX tunnel (ansible.makeitwork.cloud)
56+
resource "cloudflare_zero_trust_tunnel_cloudflared" "awx" {
57+
account_id = local.account_id
58+
name = "awx"
59+
}
60+
61+
resource "cloudflare_dns_record" "ansible_tunnel" {
62+
zone_id = local.zone_id
63+
type = "CNAME"
64+
name = "ansible"
65+
content = "${cloudflare_zero_trust_tunnel_cloudflared.awx.id}.cfargotunnel.com"
66+
proxied = true
67+
ttl = 1
68+
}
69+
70+
# =============================================================================
71+
# WARP Connector (IP routing for Zero Trust VPN)
72+
# =============================================================================
73+
74+
resource "cloudflare_zero_trust_tunnel_cloudflared" "warp" {
75+
account_id = local.account_id
76+
name = "warp-connector"
77+
}
78+
79+
resource "cloudflare_zero_trust_tunnel_cloudflared_route" "private_network" {
80+
account_id = local.account_id
81+
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.warp.id
82+
network = local.warp_private_network
83+
}

main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ locals {
77
zone_id = data.sops_file.secret_vars.data["cloudflare_zone_id"]
88
github_warp_client_id = data.sops_file.secret_vars.data["github_warp_client_id"]
99
github_warp_client_secret = data.sops_file.secret_vars.data["github_warp_client_secret"]
10+
11+
# Private networks (CIDR protected via SOPS)
12+
warp_private_network = data.sops_file.secret_vars.data["warp_private_network"]
1013
}
1114

1215
data "cloudflare_zone" "makeitwork_cloud" {

outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Tunnel IDs (safe to expose - needed for kustomize-cluster ConfigMaps)
2+
# NOTE: Tunnel secrets are NOT output here - they are managed via SOPS
3+
# in both this repo (secrets/secrets.yaml) and kustomize-cluster
4+
5+
output "tunnel_ids" {
6+
description = "Cloudflare Tunnel IDs for reference in kustomize-cluster ConfigMaps"
7+
value = {
8+
argocd = cloudflare_zero_trust_tunnel_cloudflared.argocd.id
9+
grafana = cloudflare_zero_trust_tunnel_cloudflared.grafana.id
10+
uptime_kuma = cloudflare_zero_trust_tunnel_cloudflared.uptime_kuma.id
11+
awx = cloudflare_zero_trust_tunnel_cloudflared.awx.id
12+
warp = cloudflare_zero_trust_tunnel_cloudflared.warp.id
13+
}
14+
}

secrets/secrets.yaml

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
s3_bucket: ENC[AES256_GCM,data:ECQtaAJzAOPSLPEUXiG1F5KJKr6isX0c,iv:LQLfdkGZHDNkeUqTKSfw3W+zOhm4zinLFq8z0eYEadM=,tag:51QPMfS8oXagbgnK/tl9SA==,type:str]
2-
s3_key: ENC[AES256_GCM,data:TkOCluW8NzhrEQ3MifmQHLA=,iv:J63vTKw7Fulair4JwQj3FtRGGHIIVR+A1xha2QePe7k=,tag:nZA1YXPMNmaxm17pQqIqbQ==,type:str]
3-
s3_region: ENC[AES256_GCM,data:uMUPCcGphbBc,iv:XzSQxjexZ+HiF9JEHlv0a3eJI7iaFhwmo5tepqH9yQs=,tag:S0OEyg17OQZiCtaX4/1wkg==,type:str]
4-
s3_access_key: ENC[AES256_GCM,data:EuKP6SrNR4q7Ocfk94IPlN29UiM=,iv:PE2buWSo4ZawKyLJIqbNS8g5eXP+lSCRxCybu4o3wDo=,tag:o6CAuJ3/phiRXVEWXRsjcg==,type:str]
5-
s3_secret_key: ENC[AES256_GCM,data:71LUCw0T6r43Vk3LnACNyBUBCI9+prVGDjvbHfmdkxk3/5kfzhWLyA==,iv:TlHg5KY8MXf/VNL6ay24eRrUMrSy/nC5wHvFsLcSrRE=,tag:7K1WpvUtaNYf3pUDO7uZ5w==,type:str]
6-
cloudflare_api_token: ENC[AES256_GCM,data:dYCY2mPnqByFkRuPvtK1yuyoxFA6DiANTMsd5lcl3RtA8pV+JCM6kg==,iv:naDR7NK4HxAlkwXrOhUc6byZBlQE2hL939r2tvZGA5s=,tag:MRyxtPLg2UKX43Edg/c/7A==,type:str]
7-
cloudflare_account_id: ENC[AES256_GCM,data:Y8RQ38yMR0lOGvP5OXTsx8X4WYNxl72FxNlSaimd47w=,iv:9d0bpeAF32gNjFs+nbCf6zMDNgLoXwiwrwhznkAqPEg=,tag:X8HzrA7H3litXA4HGBdGNw==,type:str]
8-
cloudflare_zone_id: ENC[AES256_GCM,data:996WSh3SRmgmDuhgO30szQsf1Mda4TmRAYlwx1/3mwk=,iv:ejTj8Iqc+1uCzabVnf64FUft8OUB9tnPyi9hluQhcUA=,tag:E6WYbb+yj/OI7YhmsQsZhw==,type:str]
9-
github_warp_client_id: ENC[AES256_GCM,data:q5swiYRx6XpPPnqvXFzUPtrUxVg=,iv:3wk7Rktt4YfBpp7qbSnkWIW59Wq08tQbqfkoxKMskgU=,tag:4xtBaWYPPdBBEmXGCHJGFA==,type:str]
10-
github_warp_client_secret: ENC[AES256_GCM,data:yLK1kJ7PkgzxE7u7XXVDh+nHVVWJEtYI6aZxpL2A/iYX/ua6RjGv6g==,iv:mDRLO8BAAOIQln9hZgR0xBZMw6fQCezRCZd+svVjxtk=,tag:BACS9ZuwBwP57qHGcwBiKA==,type:str]
1+
s3_bucket: ENC[AES256_GCM,data:5TMa3shAi5AWwBZXJwhXqlFkkltpZ+32,iv:FrkLf/Tpt6F95Wq+ha7+Ft6Rd155ks+auZg7fji2crw=,tag:4dwzrFCR/+DB/aclCnUmTw==,type:str]
2+
s3_key: ENC[AES256_GCM,data:KGRVuiLT40P+NZ+tQApvUw4=,iv:ogzG1Dik4RPys9I5f1bIhv8mBAqZZbhXGOIHh8SANJE=,tag:kmNaJ3A1Zl009eFGa42Eew==,type:str]
3+
s3_region: ENC[AES256_GCM,data:REQaSpV5XaxF,iv:XwIKsBhKN79J02C9i1rcaELlW3XZyCUXxcFWEl3e8Tc=,tag:LYkbKbIEW5Tbu3uA+LbT1A==,type:str]
4+
s3_access_key: ENC[AES256_GCM,data:xXq9LdhfKMJt4WIMutITgFnfpKE=,iv:GwNs2X0zMpQF0q2chPY45Mr2drzDXalQ2T4P2Pi99Rc=,tag:hTpN50TPn9Ne0iKSvEcuXw==,type:str]
5+
s3_secret_key: ENC[AES256_GCM,data:bI0MXQJuTCVhSyn23L6zmYwCS4VDaJiHMWasEz3lvT2PQLJCWRzOBg==,iv:9KaiyFUhctHH+BZ//hnMLOiizl0fizWyBW88UA7bRK8=,tag:d78Xa9k4M2MET7OMMM+vbA==,type:str]
6+
cloudflare_api_token: ENC[AES256_GCM,data:vmeV+PnkzqQd1yfCfKPOKJtdDlL7D2upfyg37owfmOK6N7KT6D0MHg==,iv:F0Casb8Fkcle38opykiNvxmNg0e4N4e/d7dm39m2UIU=,tag:p7Vpd+V9QNoV+3ceDEmu8A==,type:str]
7+
cloudflare_account_id: ENC[AES256_GCM,data:XDcHnUnXcRgc6MfOkD/+EBVvofIKBobS7BgNWYbG7i4=,iv:L671lt/PO6vEWljiSjOzL2TJ/vVtbgWnFXuUdalkCa0=,tag:2BzFXVXg6hzz3m14oeFI/Q==,type:str]
8+
cloudflare_zone_id: ENC[AES256_GCM,data:LKHkFih/CAwDTkGljcEumEK5MF2jWgxXCntuw1yQjuk=,iv:nCYxPSJaV4wTnciwJ7bQh7BxMKh2TDc+pt1a1JdZPuA=,tag:TRh7624huZBu+rwRiWJRTQ==,type:str]
9+
github_warp_client_id: ENC[AES256_GCM,data:AQQlcqw+uoV8ysCYGP+vasI2obU=,iv:FZdjzL9ofCatd/IZc2ceJQS9Ls2OyltHJ8UGkXIbJL4=,tag:RvP7CHLGGA2QG9cDIv7qxA==,type:str]
10+
github_warp_client_secret: ENC[AES256_GCM,data:/9PdKHBNkCvb+3uaPhkgjQ/d/7uO/BKKuPLJ51/519TpjGiwnXwtDg==,iv:c1ZmcSQnGMzyQzH9DlcIK54u4XVH8ZNCZUXW9HMiJBg=,tag:Iv1OKBh78QOxCoboyucE0Q==,type:str]
11+
#ENC[AES256_GCM,data:NRrIGgCWh0MOpRWx7Cw6wCaZLcOxoCEjXmQ+rwrFfhe2myjGHRA=,iv:EUxsPxSb1dKAMGrLEhipLdvi2ASXVRK7c8MWoHHYIyQ=,tag:ZdPL96rSbeF7JI8i0aABNA==,type:comment]
12+
warp_private_network: ENC[AES256_GCM,data:GgohATv3bceMezxfesM=,iv:SypBrFaK1DAH5DLca0dodfeV0uZ7pTEh/5WamdFj0u4=,tag:Zv28Trazx45VCLGyCilbmQ==,type:str]
1113
sops:
1214
age:
1315
- recipient: age152ek83tm4fj5u70r3fecytn4kg7c5xca24erjchxexx4pfqg6das7q763l
1416
enc: |
1517
-----BEGIN AGE ENCRYPTED FILE-----
16-
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1d1dmSGFXRnQxSXJvWkNP
17-
VFdxdllqWFVQdmVVY2hQNy9aSFJiSkVWQzBVCjdkZGJycDkvWkxPdzhrdlNGVlFZ
18-
eWVkVnJhblFuTWRpbWVXbHJPRHpPUUUKLS0tIHQvU2RzOW9ET0hWd3ZUQ01ibE1w
19-
dWYwMHFjSFBjbmE5cFl1U2hJdTZqczgK5uy8SJWSzIc7SjLq8NdnRP+hcN3DAk4r
20-
MTU5T82eqjJ8vLDTPbAABIrSHYNhsf2DCNY1jtgqyofo3NvmjZLzMg==
18+
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTQktvS3NPcGRXaGwzc254
19+
TGEwMlBkWXZ2dGRtMFdDNmpMdHViVDducER3CmtNY3pnNDkrZ2RnMmZVakx1ZlBU
20+
a3l1UUZ1bmlmVHM0eTBqZHZIeG94dEkKLS0tIFlRYU5WeFR3VlViUlFBa0ZCKzFC
21+
MTBFY21HTlhGV01tM0pVRGFuc1E5NVUKZE2VS+5cYdHhcSkZlLlX7nvfW3PLuSK7
22+
ostSDKZK935LA6iiZoIk7Q9l4xPenhOXv6Oi6uXWq4sJXLAYC2qX1w==
2123
-----END AGE ENCRYPTED FILE-----
22-
lastmodified: "2025-12-28T06:58:50Z"
23-
mac: ENC[AES256_GCM,data:qTIgZM7d7OoH00rh4EXVgpju9hzCnCwFJi8q99AgGxpRZvuq6/vTzWGgFgHvn6WcgXpV5DAB70hOKt2F7E7VGujaP3ey4oQDwcbzZ9Q6l7u3MyRwz8KU9m4BOIrHfeIIWS6CxUbZSH2fVugoK4XomnHn8kocjT6Xm0dNWWBRyew=,iv:NMEGiKVlOMXzDbMGTiYVqeyMhzOdF5btVCc2HZKvu9I=,tag:GIJlGOjqL77KrhDlZ6x7oA==,type:str]
24+
lastmodified: "2025-12-28T21:48:14Z"
25+
mac: ENC[AES256_GCM,data:zYZY9hVSuVwvY8ZmAi+IjgppQxZ76alGESUe2QG3DEiS71uBdOuzZ/4PSMbV95BU8HMmDuFI06BUV8FWSGVM6izWfiQbwWYZmXdAG+wlbIBoKMkO0TuqvD718G6dK5ecPc/8GZxU+dsjWc9hnT7q42ZYw1GjRYY8g3L+9vfNeVs=,iv:M1AGFXYgfkDE3LyVH32M2opv/SYH2phEfHWYl6DeJrY=,tag:HscClM9n5GP9QMU9Ekkt1g==,type:str]
2426
unencrypted_suffix: _unencrypted
2527
version: 3.10.2

0 commit comments

Comments
 (0)