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

@ -6,6 +6,7 @@ variable "k8s_users" {
role = string # "admin", "power-user", "namespace-owner"
email = string # OIDC email claim
namespaces = optional(list(string), []) # for namespace-owners
domains = optional(list(string), []) # subdomains for user apps
quota = optional(object({
cpu_requests = optional(string, "2")
memory_requests = optional(string, "4Gi")
@ -248,3 +249,15 @@ resource "kubernetes_config_map" "user_roles" {
})
}
}
# TLS secret in each user namespace (so they can create HTTPS ingresses)
module "user_namespace_tls" {
for_each = nonsensitive(toset(flatten([
for name, user in var.k8s_users : user.namespaces
if user.role == "namespace-owner"
])))
source = "../../../../modules/kubernetes/setup_tls_secret"
namespace = each.value
tls_secret_name = var.tls_secret_name
}