add generic multi-user cluster onboarding system

Data-driven user onboarding: add a JSON entry to Vault KV k8s_users,
apply vault + platform + woodpecker stacks, and everything is auto-generated.

Vault stack: namespace creation, per-user Vault policies with secret isolation
via identity entities/aliases, K8s deployer roles, CI policy update.

Platform stack: domains field in k8s_users type, TLS secrets per user namespace,
user domains merged into Cloudflare DNS, user-roles ConfigMap mounted in portal.

Woodpecker stack: admin list auto-generated from k8s_users, WOODPECKER_OPEN=true.

K8s-portal: dual-track onboarding (general/namespace-owner), namespace-owner
dashboard with Vault/kubectl commands, setup script adds Vault+Terraform+Terragrunt,
contributing page with CI pipeline template, versioned image tags in CI pipeline.

New: stacks/_template/ with copyable stack template for namespace-owners.
This commit is contained in:
Viktor Barzin 2026-03-15 22:23:36 +00:00 committed by Viktor Barzin
parent 5bc50af99e
commit 0610ea30d4
13 changed files with 530 additions and 40 deletions

View file

@ -68,6 +68,12 @@ locals {
mailserver_aliases = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_aliases"])
mailserver_opendkim_key = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_opendkim_key"])
mailserver_sasl_passwd = jsondecode(data.vault_kv_secret_v2.secrets.data["mailserver_sasl_passwd"])
# User domains from namespace-owners for DNS/Cloudflare
user_domains = flatten([
for name, user in local.k8s_users : user.domains
if user.role == "namespace-owner"
])
}
# =============================================================================
@ -377,7 +383,7 @@ module "cloudflared" {
cloudflare_zone_id = var.cloudflare_zone_id
cloudflare_tunnel_id = var.cloudflare_tunnel_id
public_ip = var.public_ip
cloudflare_proxied_names = var.cloudflare_proxied_names
cloudflare_proxied_names = concat(var.cloudflare_proxied_names, 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"]
}