Production-aligned · Platform-owned · GitOps-managed · Kubernetes-native
This repository implements a platform-owned autoscaling layer for Kubernetes workloads using Horizontal Pod Autoscaler (HPA) and KEDA, enforced via Kyverno policies and delivered entirely through GitOps.
The goal is not to teach autoscaling mechanics, but to formalize clear ownership boundaries:
- The platform owns autoscaling behavior, limits, and safety
- Workloads select an approved autoscaling profile only
Autoscaling is treated as a governed platform capability, not an application-level free-for-all.
This repository assumes a cluster created by the
gitops-karpenter-platform
infrastructure layer.
- Prevents ad‑hoc, unsafe autoscaling definitions in workloads
- Centralizes scaling limits, cooldowns, and allowed triggers
- Enforces deterministic, reviewable autoscaling behavior
- Supports both CPU-based and event-driven scaling without overlap
- Autoscaling profile definitions (HPA / KEDA)
- Kyverno admission policies and guardrails
- Namespace-level autoscaling enable/disable switch
- Validation of scaling limits, metrics, and triggers
- Application business logic
- Performance tuning inside containers
- Infrastructure provisioning
- Capacity provisioning (nodes)
Autoscaling policy is decoupled from infrastructure capacity.
- Define allowed autoscaling profiles
- Enforce scaling limits and cooldown behavior
- Prevent unsafe or unsupported autoscaling configurations
- Ensure autoscaling behavior is predictable and auditable
- Select an approved autoscaling profile
- Declare resource requests
- Remain agnostic of autoscaling mechanics
Key principle: workloads opt in to behavior; the platform enforces it.
The platform supports two distinct autoscaling paradigms, intentionally separated.
- CPU-based scaling
- Deterministic and conservative
- Suitable for request/response workloads
- Queue/event-based scaling
- Supports scale-to-zero
- Suitable for async workers and background processing
HPA and KEDA must not overlap on the same workload.
Autoscaling behavior is selected via an explicit label:
autoscaling.profile: <profile-name>| Profile | Type | Description |
|---|---|---|
hpa-default |
HPA | CPU-based scaling with fixed limits |
keda-events-queue |
KEDA | Redis queue–based event scaling |
Profiles are validated and enforced by Kyverno. Invalid configurations are rejected at admission time.
Detailed contract definitions, constraints, and the extension model for autoscaling profiles are documented separately:
That document is the authoritative reference for:
- which profiles are implemented
- which profiles are intentionally not exposed
- how the platform can be extended safely and incrementally without breaking existing workload contracts
Autoscaling can be disabled per namespace:
autoscaling.platform.io/enabled: "false"When disabled:
- Any autoscaling profile usage is denied
- Violations fail fast at admission time
Enforced constraints include:
- CPU metric only
- Fixed target utilization
- Maximum replica cap
- Mandatory scale-down stabilization window
Workloads cannot modify these parameters.
Enforced constraints include:
- Scale-to-zero enabled
- Maximum replica cap
- Mandatory cooldown period
- Redis trigger only
- Required metadata (
address,listName)
Only approved event sources are allowed.
[ Git Repository ]
↓
[ Argo CD ]
↓
[ Kyverno Policies ]
↓
[ HPA / KEDA Controllers ]
↓
[ Workload Pods ]
Autoscaling intent is validated at admission time via Kyverno policies and continuously reconciled via GitOps by Argo CD.
Runtime scaling decisions are then executed by the native Kubernetes controllers (HPA / KEDA) based strictly on the platform-approved contracts.
A more detailed, lower-level architecture diagram is available in
docs/architecture-diagram.mmd.
gitops-autoscaling-platform/
├── README.md
├── docs/ # Platform documentation (contracts, install, validation)
└── gitops/
├── bootstrap/
│ └── argocd/ # Argo CD bootstrap (one-time)
│
├── argo/
│ ├── applicationsets/ # App-of-Apps & environment wiring
│ └── projects/ # Argo CD project boundaries
│
└── apps/
├── platform/ # Platform-owned components
│ ├── autoscaling/
│ │ ├── enforcement/ # Kyverno autoscaling guardrails
│ │ └── values/ # KEDA Helm values
│ ├── kyverno/ # Kyverno deployment (Helm)
│ ├── external-dns/ # DNS automation
│ ├── traefik/ # Ingress controller
│ └── namespaces/ # Platform-owned namespaces
│
└── workloads/ # Application workloads
└── <app>/
├── base/ # Environment-agnostic manifests
└── overlays/
└── dev/ # Environment-specific overlays
Domain names, DNS automation, and TLS termination details are documented separately in
docs/domain-configuration.md.
This repository does not provision infrastructure.
It is designed to be applied directly on top of an existing Kubernetes cluster that already provides:
- a running Kubernetes cluster (e.g. Amazon EKS)
- Argo CD installed and reachable
- metrics-server (required for HPA)
- admission webhooks enabled (required for Kyverno)
In the reference setup, these prerequisites are provisioned by a separate infrastructure repository:
That repository is responsible for:
- VPC and networking
- Kubernetes cluster lifecycle (EKS)
- bootstrap / system node groups
- Karpenter installation and AWS-side prerequisites
This repository intentionally does not duplicate or manage any infrastructure logic. It consumes the cluster produced by the infrastructure layer and focuses strictly on policy-driven autoscaling and platform enforcement.
The complete installation and bootstrap flow for this repository is documented separately:
That document covers:
- prerequisites and external dependencies (as consumed by this repo)
- Argo CD project bootstrap
- App-of-Apps initialization
- autoscaling platform reconciliation order
Follow the installation guide before attempting any validation or demo scenarios.
This repository includes explicit demo guides to validate autoscaling behavior in a real cluster after installation.
These documents are not part of the installation flow. They exist to verify and demonstrate platform enforcement.
Quick validation of CPU-driven Horizontal Pod Autoscaler behavior:
Demonstrates:
- metrics-server dependency
- deterministic scale-up / scale-down
- Kyverno-enforced HPA defaults
Quick validation of event-based autoscaling using a Redis queue:
Demonstrates:
- scale-to-zero behavior
- Redis-triggered scaling
- Kyverno-enforced KEDA profile
- expected HPA artifacts for external metrics
These demos are intentionally minimal and designed for observability and correctness, not load testing.
- Autoscaling is a platform concern
- Policies are explicit and enforceable
- No silent defaults or hidden behavior
- Admission-time failures over runtime surprises
- GitOps as the single source of truth
This repository is designed as a single platform layer and is intended to be composed with other dedicated platform repositories.
- GitOps Karpenter Platform — Capacity & Scheduling Layer
Platform-owned capacity, node architecture, and disruption control.
Autoscaling policies in this repository are designed to run on top of this layer.
https://github.com/LaurisNeimanis/gitops-karpenter-platform
- AWS EKS GitOps Layer (Argo CD)
Out-of-band GitOps control plane managing platform services and workloads.
https://github.com/LaurisNeimanis/aws-eks-gitops
- Kubernetes Observability Stack (GitOps-managed)
Metrics and logs used for validation, debugging, and operational feedback.
https://github.com/LaurisNeimanis/gitops-observability-stack
- Autoscaling optimization per application
- Dynamic, workload-defined scaling behavior
- Blending HPA and KEDA on the same workload
- Teaching autoscaling fundamentals or Kubernetes basics
This repository is intentionally strict, minimal, and opinionated.
It exists to demonstrate policy-driven autoscaling ownership using production-aligned Kubernetes primitives.