infra/stacks/platform/modules/rbac/audit-policy.tf
Viktor Barzin e6420c7b36 [ci skip] Move Terraform modules into stack directories
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.
2026-02-22 14:38:14 +00:00

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]
}