Hari 35: Rego Policy Pertama — Wajib Resource Limits
4 min read

Hari 35: Rego Policy Pertama — Wajib Resource Limits

Tulis Rego policy pertama untuk Gatekeeper: Pod/Deployment tanpa resource limits dan requests ditolak. 4 violation rules, enforcementAction deny, 0 violations.

devsecops
kubernetes
opa gatekeeper
rego
policy as code
Share

Hari 34 kemarin install OPA Gatekeeper — "bouncer" di pintu masuk cluster. Tapi bouncer-nya belum punya aturan. Hari ini tulis aturan pertama: Pod tanpa resource limits dan requests = ditolak.

Kenapa Resource Limits Penting?

Tanpa resource limits, Pod bisa menghabiskan CPU/memory node — menyebabkan DoS (Denial of Service) ke Pod lain di node yang sama. Kubernetes scheduler juga butuh resource requests untuk decision placement Pod ke node yang tepat.

Scanner seperti Checkov dan Trivy sudah menandai "no resources" sebagai finding (Day 32). Tapi scanner hanya melaporkan — tidak mencegah. Gatekeeper mencegah: Pod tanpa resources tidak akan masuk ke cluster, titik.

Dua File: ConstraintTemplate + Constraint

Gatekeeper punya konsep 2 layer:

ConstraintTemplate — berisi Rego policy code. Ini "template" yang mendefinisikan logic: "Kalau Pod tidak punya CPU limit = violation". Analoginya seperti template undangan.

Constraint — instance dari template. Berisi match rules: policy ini berlaku untuk Pod dan Deployment di namespace securebank saja, dengan enforcementAction: deny. Analoginya seperti undangan yang sudah dikirim ke tamu tertentu.

Satu template bisa punya banyak constraint — misalnya deny untuk production, dryrun untuk development.

Rego Policy: 4 Violation Rules

package k8srequiredlimits

# Rule 1: CPU limit wajib
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  not container.resources.limits.cpu
  msg := sprintf("Container '%v' has no CPU limit", [container.name])
}

# Rule 2: Memory limit wajib
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  not container.resources.limits.memory
  msg := sprintf("Container '%v' has no memory limit", [container.name])
}

# Rule 3: CPU request wajib
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  not container.resources.requests.cpu
  msg := sprintf("Container '%v' has no CPU request", [container.name])
}

# Rule 4: Memory request wajib
violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  not container.resources.requests.memory
  msg := sprintf("Container '%v' has no memory request", [container.name])
}

Tutorial cuma cek limits (2 rules). Aku tambah requests juga (4 rules total) — lebih comprehensive. Requests penting untuk scheduler: kalau tidak ada, scheduler tidak tahu berapa resource yang Pod butuhkan, bisa placement ke node yang salah.

Rego Syntax Yang Dipelajari

  • violation[{"msg": msg}] — Gatekeeper pattern: kalau rule ini match, ada violation dengan pesan error
  • input.review.object — resource yang sedang di-apply (Pod atau Deployment)
  • spec.containers[_] — iterasi semua container di Pod
  • not container.resources.limits.cpunot = negation. Kalau property tidak ada = true (violation)
  • sprintf("Container '%v' ...", [container.name]) — format string dengan container name

Constraint: Match Rules + Enforcement

spec:
  enforcementAction: deny
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
    namespaces:
      - securebank
  • enforcementAction: deny — explicit deny. Bisa juga dryrun (allow tapi report) atau warn (allow dengan warning)
  • apiGroups: [""] + kinds: ["Pod"] — match bare Pod
  • apiGroups: ["apps"] + kinds: ["Deployment"] — match Deployment (Gatekeeper expand ke Pod template)
  • namespaces: ["securebank"] — hanya di namespace securebank

Hasil: 0 Violations

Setelah apply, verifikasi:

$ kubectl get k8srequiredlimits require-resource-limits
NAME                      ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
require-resource-limits   deny

0 total violations. Artinya deployment.yaml yang sudah di-hardened di Day 33 (dengan resources: requests + limits) langsung pass policy. Tidak perlu fix apa-apa.

Before vs After

Aspek Before (Day 34) After (Day 35)
Policy Gatekeeper installed, no policy Rego policy: 4 violation rules
Enforcement Webhook aktif tapi kosong Pod tanpa resources = ditolak
Scope Namespace securebank only
enforcementAction deny (explicit)
Violations 0 (existing deployment compliant)

Pelajaran Hari Ini

ConstraintTemplate = template, Constraint = instance. Template berisi Rego code (logic). Constraint berisi match rules (scope) + enforcementAction. Satu template bisa punya banyak constraint dengan enforcementAction berbeda.

not di Rego = negation. Rego tidak punya == nil atau != nil seperti Go. not container.resources.limits.cpu artinya "kalau property ini tidak ada". Simple tapi butuh adaptasi dari mindset Go/Python.

Scanner melaporkan, Gatekeeper mencegah. Checkov dan Trivy menemukan "no resources" di Day 32. Tapi scanner hanya laporkan — developer bisa ignore. Gatekeeper mencegah: kubectl apply Pod tanpa resources = ditolak. Prevention > detection.

Repo

Semua code dan dokumentasi ada di: https://github.com/stayrelevantid/chalange-devsecops

Kesimpulan

Rego policy pertama berhasil. 4 violation rules (CPU limit, memory limit, CPU request, memory request), enforcementAction: deny, 0 violations. Besok Day 36 — test policy-nya bekerja: apply Pod tanpa resources → expect ditolak. Apply Pod dengan resources → expect diterima. Menuju policy-as-code di K8s cluster.

Enjoyed this article? Share it!

Share

Diskusi & Komentar

Artikel Terkait