extract monitoring, nvidia, mailserver, cloudflared, kyverno from platform [ci skip]

Phase 2 of platform stack split. 5 more modules extracted into
independent stacks. All applied successfully with zero destroys.
Cloudflared now reads k8s_users from Vault directly to compute
user_domains. Woodpecker pipeline runs all 8 extracted stacks
in parallel. Memory bumped to 6Gi for 9 concurrent TF processes.
Platform reduced from 27 to 19 modules.
This commit is contained in:
Viktor Barzin 2026-03-17 21:34:11 +00:00
parent 3c804aedf8
commit ae36dc253b
73 changed files with 166093 additions and 96 deletions

View file

@ -0,0 +1,42 @@
# =============================================================================
# Cloudflared Stack Cloudflare tunnel + DNS records
# =============================================================================
variable "tls_secret_name" { type = string }
variable "cloudflare_email" { type = string }
variable "cloudflare_account_id" { type = string }
variable "cloudflare_zone_id" { type = string }
variable "cloudflare_tunnel_id" { type = string }
variable "public_ip" { type = string }
variable "cloudflare_proxied_names" {}
variable "cloudflare_non_proxied_names" {}
data "vault_kv_secret_v2" "secrets" {
mount = "secret"
name = "platform"
}
locals {
k8s_users = jsondecode(data.vault_kv_secret_v2.secrets.data["k8s_users"])
user_domains = flatten([
for name, user in local.k8s_users : lookup(user, "domains", [])
if user.role == "namespace-owner"
])
}
module "cloudflared" {
source = "./modules/cloudflared"
tier = local.tiers.core
tls_secret_name = var.tls_secret_name
cloudflare_api_key = data.vault_kv_secret_v2.secrets.data["cloudflare_api_key"]
cloudflare_email = var.cloudflare_email
cloudflare_account_id = var.cloudflare_account_id
cloudflare_zone_id = var.cloudflare_zone_id
cloudflare_tunnel_id = var.cloudflare_tunnel_id
public_ip = var.public_ip
cloudflare_proxied_names = concat(var.cloudflare_proxied_names, nonsensitive(local.user_domains))
cloudflare_non_proxied_names = var.cloudflare_non_proxied_names
cloudflare_tunnel_token = data.vault_kv_secret_v2.secrets.data["cloudflare_tunnel_token"]
}

View file

@ -0,0 +1,159 @@
# Contents for cloudflare account
variable "cloudflare_api_key" {}
variable "cloudflare_email" {}
variable "cloudflare_proxied_names" { type = list(string) }
variable "cloudflare_non_proxied_names" { type = list(string) }
variable "cloudflare_zone_id" {
description = "Zone ID for your domain"
type = string
}
variable "cloudflare_account_id" {
type = string
sensitive = true
}
variable "cloudflare_tunnel_id" {
type = string
sensitive = true
}
variable "public_ip" {
type = string
}
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4"
}
}
}
provider "cloudflare" {
api_key = var.cloudflare_api_key # I gave up on getting the permissions on the token...
email = var.cloudflare_email
}
locals {
cloudflare_proxied_names_map = {
for h in var.cloudflare_proxied_names :
h => h
}
cloudflare_non_proxied_names_map = {
for h in var.cloudflare_non_proxied_names :
h => h
}
}
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "sof" {
account_id = var.cloudflare_account_id
tunnel_id = var.cloudflare_tunnel_id
config {
warp_routing {
enabled = true
}
dynamic "ingress_rule" {
for_each = toset(var.cloudflare_proxied_names)
content {
hostname = ingress_rule.value == "viktorbarzin.me" ? ingress_rule.value : "${ingress_rule.value}.viktorbarzin.me"
path = "/"
service = "https://10.0.20.202:443"
origin_request {
no_tls_verify = true
}
}
}
ingress_rule {
service = "http_status:404"
}
}
}
resource "cloudflare_record" "dns_record" {
# count = length(var.cloudflare_proxied_names)
# name = var.cloudflare_proxied_names[count.index]
for_each = local.cloudflare_proxied_names_map
name = each.key
content = "${var.cloudflare_tunnel_id}.cfargotunnel.com"
proxied = true
ttl = 1
type = "CNAME"
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "non_proxied_dns_record" {
# count = length(var.cloudflare_non_proxied_names)
# name = var.cloudflare_non_proxied_names[count.index]
for_each = local.cloudflare_non_proxied_names_map
name = each.key
# content = var.non_proxied_names[count.index].ip
content = var.public_ip
proxied = false
ttl = 1
type = "A"
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "mail" {
content = "mail.viktorbarzin.me"
name = "viktorbarzin.me"
proxied = false
ttl = 1
type = "MX"
priority = 1
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "mail_domainkey" {
content = "\"k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIDLB8mhAHNqs1s6GeZMQHOxWweoNKIrqo5tqRM3yFilgfPUX34aTIXNZg9xAmlK+2S/xXO1ymt127ZGMjnoFKOEP8/uZ54iHTCnioHaPZWMfJ7o6TYIXjr+9ShKfoJxZLv7lHJ2wKQK3yOw4lg4cvja5nxQ6fNoGRwo+mQ/mgJQIDAQAB\""
name = "s1._domainkey.viktorbarzin.me"
proxied = false
ttl = 1
type = "TXT"
priority = 1
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "mail_spf" {
content = "\"v=spf1 include:mailgun.org ~all\""
name = "viktorbarzin.me"
proxied = false
ttl = 1
type = "TXT"
priority = 1
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "mail_dmarc" {
content = "\"v=DMARC1; p=quarantine; pct=100; fo=1; ri=3600; sp=quarantine; adkim=r; aspf=r; rua=mailto:e21c0ff8@dmarc.mailgun.org,mailto:adb84997@inbox.ondmarc.com; ruf=mailto:e21c0ff8@dmarc.mailgun.org,mailto:adb84997@inbox.ondmarc.com,mailto:postmaster@viktorbarzin.me;\""
name = "_dmarc.viktorbarzin.me"
proxied = false
ttl = 1
type = "TXT"
priority = 1
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "keyserver" {
content = "130.162.165.220" # Oracle VPS
name = "keyserver.viktorbarzin.me"
proxied = false
ttl = 3600
type = "A"
priority = 1
zone_id = var.cloudflare_zone_id
}
# Enable HTTP/3 (QUIC) for Cloudflare-proxied domains
resource "cloudflare_zone_settings_override" "http3" {
zone_id = var.cloudflare_zone_id
settings {
http3 = "on"
}
}

View file

@ -0,0 +1,130 @@
# Contents for cloudflare tunnel
variable "tls_secret_name" {}
variable "cloudflare_tunnel_token" {}
resource "kubernetes_namespace" "cloudflared" {
metadata {
name = "cloudflared"
labels = {
tier = var.tier
}
}
}
variable "tier" { type = string }
module "tls_secret" {
source = "../../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.cloudflared.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "cloudflared" {
metadata {
name = "cloudflared"
namespace = kubernetes_namespace.cloudflared.metadata[0].name
labels = {
app = "cloudflared"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 3
strategy {
type = "RollingUpdate"
}
selector {
match_labels = {
app = "cloudflared"
}
}
template {
metadata {
labels = {
app = "cloudflared"
}
}
spec {
topology_spread_constraint {
max_skew = 1
topology_key = "kubernetes.io/hostname"
when_unsatisfiable = "ScheduleAnyway"
label_selector {
match_labels = {
app = "cloudflared"
}
}
}
container {
# image = "wisdomsky/cloudflared-web:latest"
image = "cloudflare/cloudflared"
name = "cloudflared"
command = ["cloudflared", "tunnel", "run"]
env {
name = "TUNNEL_TOKEN"
value = var.cloudflare_tunnel_token
}
port {
container_port = 14333
}
resources {
requests = {
cpu = "15m"
memory = "128Mi"
}
limits = {
memory = "128Mi"
}
}
}
dns_config {
option {
name = "ndots"
value = "2"
}
}
}
}
}
}
resource "kubernetes_pod_disruption_budget_v1" "cloudflared" {
metadata {
name = "cloudflared"
namespace = kubernetes_namespace.cloudflared.metadata[0].name
}
spec {
max_unavailable = "1"
selector {
match_labels = {
app = "cloudflared"
}
}
}
}
resource "kubernetes_service" "cloudflared" {
metadata {
name = "cloudflared"
namespace = kubernetes_namespace.cloudflared.metadata[0].name
labels = {
"app" = "cloudflared"
}
}
spec {
selector = {
app = "cloudflared"
}
port {
name = "http"
target_port = 14333
port = 80
protocol = "TCP"
}
}
}

1
stacks/cloudflared/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

View file

@ -0,0 +1,8 @@
include "root" {
path = find_in_parent_folders()
}
dependency "infra" {
config_path = "../infra"
skip_outputs = true
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}