diff --git a/README.md b/README.md index a5ee0e5..4e8056b 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ accidentally modify the cluster. - installs OpenEBS - creates `openebs-hostpath-retain` - installs Argo CD + - installs Kyverno with audit-first baseline Pod Security policies - registers the private GitOps repo without storing the SSH private key in Terraform state @@ -189,6 +190,14 @@ single-node rebuild. Add Helm releases through `bootstrap/platform`'s `extra_helm_releases` map. +## Policy Guardrails + +`bootstrap/platform` installs Kyverno and the upstream baseline Pod Security +policies in `Audit` mode. This gives the lab policy reports for unsafe workload +settings without blocking existing pods during the first rollout. After reports +are clean, individual policies can be promoted to `Enforce` in +`bootstrap/platform/main.tf`. + ## Edge Services The OCI jump box runs the public edge path: diff --git a/bootstrap/platform/main.tf b/bootstrap/platform/main.tf index 23f859d..c76b411 100644 --- a/bootstrap/platform/main.tf +++ b/bootstrap/platform/main.tf @@ -336,6 +336,93 @@ EOT } } +resource "helm_release" "kyverno" { + depends_on = [null_resource.calico_ready] + name = "kyverno" + repository = var.kyverno.repository + chart = "kyverno" + version = var.kyverno.chart_version + namespace = var.kyverno.namespace + create_namespace = true + timeout = 900 + wait = true + + values = [ + yamlencode({ + admissionController = { + replicas = 1 + resources = { + requests = { + cpu = "50m" + memory = "128Mi" + } + limits = { + memory = "384Mi" + } + } + } + backgroundController = { + replicas = 1 + resources = { + requests = { + cpu = "25m" + memory = "96Mi" + } + limits = { + memory = "256Mi" + } + } + } + cleanupController = { + replicas = 1 + resources = { + requests = { + cpu = "10m" + memory = "64Mi" + } + limits = { + memory = "192Mi" + } + } + } + reportsController = { + replicas = 1 + resources = { + requests = { + cpu = "25m" + memory = "96Mi" + } + limits = { + memory = "256Mi" + } + } + } + }) + ] +} + +resource "helm_release" "kyverno_policies" { + depends_on = [helm_release.kyverno] + name = "kyverno-policies" + repository = var.kyverno.repository + chart = "kyverno-policies" + version = var.kyverno.policies_version + namespace = var.kyverno.namespace + create_namespace = false + timeout = 600 + wait = true + + values = [ + yamlencode({ + podSecurityStandard = "baseline" + podSecuritySeverity = "medium" + validationFailureAction = "Audit" + validationAllowExistingViolations = true + failurePolicy = "Ignore" + }) + ] +} + resource "helm_release" "loki" { depends_on = [kubernetes_namespace_v1.monitoring] name = "loki" diff --git a/bootstrap/platform/variables.tf b/bootstrap/platform/variables.tf index ef9fb1a..84a4bf5 100644 --- a/bootstrap/platform/variables.tf +++ b/bootstrap/platform/variables.tf @@ -76,6 +76,22 @@ variable "argocd" { } } +variable "kyverno" { + type = object({ + repository = string + chart_version = string + policies_version = string + namespace = string + }) + + default = { + repository = "https://kyverno.github.io/kyverno/" + chart_version = "3.8.1" + policies_version = "3.8.0" + namespace = "kyverno" + } +} + variable "observability" { type = object({ namespace = string