Skip to content

Instantly share code, notes, and snippets.

@andymotta
Created February 20, 2023 17:44
Show Gist options
  • Save andymotta/5919912e348f8a85b159d35e0901b38e to your computer and use it in GitHub Desktop.
Save andymotta/5919912e348f8a85b159d35e0901b38e to your computer and use it in GitHub Desktop.
Deploy Cloudflare WARP (VPN tunnel) on Kubernetes
provider "cloudflare" {
api_token = var.cf_api_token
}
variable "cf_api_token" {}
variable "account_id" {}
resource "random_id" "tunnel_secret" {
byte_length = 35
}
resource "cloudflare_argo_tunnel" "warp" {
account_id = var.account_id
name = var.name
secret = random_id.tunnel_secret.b64_std
}
resource "cloudflare_tunnel_virtual_network" "k8s_zero_trust_tunnel_vnet" {
account_id = var.account_id
name = var.name
comment = var.name
is_default_network = false
}
resource "cloudflare_tunnel_route" "warp_ipv4" {
account_id = var.account_id
tunnel_id = cloudflare_argo_tunnel.warp.id
network = var.vpc_cidr_block
comment = var.name
virtual_network_id = cloudflare_tunnel_virtual_network.k8s_zero_trust_tunnel_vnet.id
}
resource "kubernetes_namespace" "cloudflare_vpn" {
metadata {
name = "vpn"
}
}
resource "kubernetes_secret" "cloudflared-creds" {
metadata {
name = "cloudflared-creds"
namespace = "vpn"
}
data = {
"creds.json" = <<EOF
{
"AccountTag" : "${var.account_id}",
"TunnelID" : "${cloudflare_argo_tunnel.warp.id}",
"TunnelName" : "${cloudflare_argo_tunnel.warp.name}",
"TunnelSecret" : "${random_id.tunnel_secret.b64_std}"
}
EOF
}
depends_on = [kubernetes_namespace.cloudflare_vpn, cloudflare_argo_tunnel.warp]
}
resource "kubernetes_config_map" "cloudflared-config" {
metadata {
name = "tunnel-zt"
namespace = "vpn"
labels = {
tunnel = "api-zt"
}
}
data = {
"config.yaml" = <<EOF
tunnel: ${cloudflare_argo_tunnel.warp.id}
protocol: quic
credentials-file: /opt/zt/creds/creds.json
metrics: 0.0.0.0:8081
no-autoupdate: true
warp-routing:
enabled: true
EOF
}
depends_on = [kubernetes_namespace.cloudflare_vpn, cloudflare_argo_tunnel.warp]
}
resource "kubernetes_deployment" "cloudflared" {
metadata {
name = "tunnel-api-zt"
namespace = "vpn"
labels = {
tunnel = "api-zt"
}
}
spec {
replicas = 2
selector {
match_labels = {
tunnel = "api-zt"
}
}
strategy {
type = "RollingUpdate"
rolling_update {
max_surge = 0
max_unavailable = 1
}
}
template {
metadata {
labels = {
tunnel = "api-zt"
}
}
spec {
container {
image = "cloudflare/cloudflared:2022.5.3"
name = "tunnel"
args = ["tunnel", "--config", "/opt/zt/config/config.yaml", "run"]
env {
name = "GOMAXPROCS"
value = 2
}
env {
name = "TZ"
value = "UTC"
}
volume_mount {
name = "config"
mount_path = "/opt/zt/config"
read_only = true
}
volume_mount {
name = "creds"
mount_path = "/opt/zt/creds"
read_only = true
}
liveness_probe {
http_get {
path = "/ready"
port = 8081
}
failure_threshold = 1
initial_delay_seconds = 10
period_seconds = 10
}
resources {
limits = {
cpu = "1"
memory = "100Mi"
}
}
port {
container_port = 8081
name = "http-metrics"
}
}
volume {
name = "creds"
secret {
secret_name = "cloudflared-creds"
}
}
volume {
name = "config"
config_map {
name = "tunnel-zt"
}
}
}
}
}
depends_on = [kubernetes_config_map.cloudflared-config, kubernetes_secret.cloudflared-creds]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment