Move all 88 service modules (66 individual + 22 platform) from modules/kubernetes/<service>/ into their corresponding stack directories: - Service stacks: stacks/<service>/module/ - Platform stack: stacks/platform/modules/<service>/ This collocates module source code with its Terragrunt definition. Only shared utility modules remain in modules/kubernetes/: ingress_factory, setup_tls_secret, dockerhub_secret, oauth-proxy. All cross-references to shared modules updated to use correct relative paths. Verified with terragrunt run --all -- plan: 0 adds, 0 destroys across all 68 stacks.
95 lines
3.6 KiB
HCL
95 lines
3.6 KiB
HCL
# Deploy audit policy to k8s-master and configure kube-apiserver to use it.
|
|
# Audit logs are written to /var/log/kubernetes/audit.log on the master node.
|
|
# Alloy (log collector DaemonSet) will pick them up and ship to Loki.
|
|
|
|
resource "null_resource" "audit_policy" {
|
|
connection {
|
|
type = "ssh"
|
|
user = "wizard"
|
|
host = var.k8s_master_host
|
|
private_key = var.ssh_private_key
|
|
}
|
|
|
|
# Upload audit policy file
|
|
provisioner "file" {
|
|
content = yamlencode({
|
|
apiVersion = "audit.k8s.io/v1"
|
|
kind = "Policy"
|
|
rules = [
|
|
{
|
|
# Don't log requests to the API discovery endpoints (very noisy)
|
|
level = "None"
|
|
resources = [{
|
|
group = ""
|
|
resources = ["endpoints", "services", "services/status"]
|
|
}]
|
|
users = ["system:kube-proxy"]
|
|
},
|
|
{
|
|
# Don't log watch requests (very noisy)
|
|
level = "None"
|
|
verbs = ["watch"]
|
|
},
|
|
{
|
|
# Don't log health checks
|
|
level = "None"
|
|
nonResourceURLs = ["/healthz*", "/readyz*", "/livez*"]
|
|
},
|
|
{
|
|
# Log secret access at Metadata level only (no request/response bodies)
|
|
level = "Metadata"
|
|
resources = [{
|
|
group = ""
|
|
resources = ["secrets"]
|
|
}]
|
|
},
|
|
{
|
|
# Log all other mutating requests at RequestResponse level
|
|
level = "RequestResponse"
|
|
verbs = ["create", "update", "patch", "delete"]
|
|
},
|
|
{
|
|
# Log read requests at Metadata level
|
|
level = "Metadata"
|
|
verbs = ["get", "list"]
|
|
},
|
|
]
|
|
})
|
|
destination = "/tmp/audit-policy.yaml"
|
|
}
|
|
|
|
provisioner "remote-exec" {
|
|
inline = [
|
|
# Move audit policy to proper location
|
|
"sudo mkdir -p /etc/kubernetes/policies",
|
|
"sudo mv /tmp/audit-policy.yaml /etc/kubernetes/policies/audit-policy.yaml",
|
|
"sudo chown root:root /etc/kubernetes/policies/audit-policy.yaml",
|
|
|
|
# Create audit log directory
|
|
"sudo mkdir -p /var/log/kubernetes",
|
|
|
|
# Check if audit flags already present
|
|
"if grep -q 'audit-policy-file' /etc/kubernetes/manifests/kube-apiserver.yaml; then echo 'Audit flags already configured'; exit 0; fi",
|
|
|
|
# Add audit flags to kube-apiserver manifest
|
|
"sudo sed -i '/- --oidc-groups-claim/a\\ - --audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml\\n - --audit-log-path=/var/log/kubernetes/audit.log\\n - --audit-log-maxage=7\\n - --audit-log-maxbackup=3\\n - --audit-log-maxsize=100' /etc/kubernetes/manifests/kube-apiserver.yaml",
|
|
|
|
# Add volume mount for audit policy (hostPath)
|
|
# The kube-apiserver pod needs access to the policy file and log directory
|
|
"sudo sed -i '/volumes:/a\\ - hostPath:\\n path: /etc/kubernetes/policies\\n type: DirectoryOrCreate\\n name: audit-policy\\n - hostPath:\\n path: /var/log/kubernetes\\n type: DirectoryOrCreate\\n name: audit-log' /etc/kubernetes/manifests/kube-apiserver.yaml",
|
|
|
|
"sudo sed -i '/volumeMounts:/a\\ - mountPath: /etc/kubernetes/policies\\n name: audit-policy\\n readOnly: true\\n - mountPath: /var/log/kubernetes\\n name: audit-log' /etc/kubernetes/manifests/kube-apiserver.yaml",
|
|
|
|
# Wait for API server to restart
|
|
"echo 'Waiting for API server to restart with audit logging...'",
|
|
"sleep 30",
|
|
"sudo kubectl --kubeconfig=/etc/kubernetes/admin.conf get nodes || echo 'API server still restarting'",
|
|
]
|
|
}
|
|
|
|
triggers = {
|
|
policy_version = "v1" # Bump to re-apply
|
|
}
|
|
|
|
depends_on = [null_resource.apiserver_oidc_config]
|
|
}
|