A portable internal developer platform built for Amazon EKS and Red Hat OpenShift (ROSA). Designed to give application teams a single golden path for deploying services while platform teams maintain security, consistency, and GitOps-driven operations.
Teams commonly lose delivery time to repeated platform work: creating deployment manifests, wiring traffic and monitoring, managing secrets, and interpreting cluster-specific security requirements. The result is inconsistent controls, slow onboarding, and production risk that increases with every service and environment.
This repository demonstrates a platform product that addresses that problem. It provides a supported application contract, environment promotion through Git, and centrally maintained guardrails. Application teams supply service configuration; the platform team owns infrastructure, delivery mechanisms, and the default controls that make a service deployable and operable.
The intended outcome is shorter lead time for new services, predictable operations across environments, and evidence-based governance without requiring every team to become Kubernetes or OpenShift specialists.
- Platform-as-product thinking — clear separation between platform team (infra, GitOps, guardrails) and app teams (Helm values only)
- Cluster-portable contract — same Helm chart, same GitOps model, same CI pipeline works on EKS and OpenShift; toggle with one values flag
- Admission-level security — OpenShift SCC enforced at cluster level vs. overridable
securityContexton EKS, with automatic handling in templates - GitOps discipline — Argo CD app-of-apps pattern, drift detection, environment promotion via Git, no
kubectl applyfor steady state - 2 tenant apps (simple-app + app-b) — same Helm contract, different values files; proves the contract scales to multiple services
- 3 environments — dev → stage → prod promotion through reviewed PRs with increasing replica counts and resource quotas
- Built-in observability — Prometheus + Grafana with pre-built dashboards, auto-discovered via ServiceMonitor
- Secret management — External Secrets Operator with ClusterSecretStore and Helm-integrated ExternalSecret template
- CI validation — Terraform fmt/validate/lint, Trivy scan, Helm lint and unit tests, manifest rendering, kubeconform, OPA policy validation, and OpenShift structural validation
# Prerequisites: kind, docker, kubectl, helm, conftest (see below)
# One command — creates cluster, installs Argo CD, deploys platform + demo app
make setupOr step by step:
make kind-up # Create local Kind cluster
make validate # Run CI checks locally (no cluster needed)
make argocd-install # Install Argo CD + AppProjects
make deploy # Bootstrap + add-ons + demo app
make clean # Delete clusterPrerequisites:
| Tool | Install |
|---|---|
| Docker | docs.docker.com/engine/install |
| kind | go install sigs.k8s.io/kind@latest |
| kubectl | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" |
| Helm | curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash |
| conftest | wget "https://github.com/open-policy-agent/conftest/releases/latest/download/conftest_$(uname -s)_$(uname -m).tar.gz" && tar xzf conftest_*.tar.gz && sudo mv conftest /usr/local/bin/ |
flowchart TB
subgraph Platform_Team["Platform Team"]
direction LR
I["infra/<br/>Terraform<br/>VPC · IAM · EKS/ROSA"]
A["argocd/<br/>AppProjects · App of Apps<br/>ApplicationSets · RBAC"]
P["platform/<br/>bootstrap · addons<br/>guardrails · network policies"]
end
subgraph Cluster["Cluster (single target)"]
C[EKS or ROSA]
end
subgraph App_Teams["App Teams"]
H["standardized-path/app/<br/>Helm contract"]
V["platform/apps/<env>/values.yaml<br/>image · port · replicas · env"]
end
Platform_Team --> Cluster
Cluster -->|Argo CD reconciles from Git| App_Teams
App teams provide (in platform/apps/<env>/values.yaml):
image, port, replicas, exposure configuration, env vars, resource requests
Platform guarantees for every deployment:
| Guarantee | Mechanism |
|---|---|
| Non-root execution | securityContext on EKS, SCC on OpenShift |
| Dropped capabilities | drop: [ALL] on EKS, default SCC on OpenShift |
| Resource boundaries | LimitRange + ResourceQuota per namespace |
| Network isolation | Default-deny network policies per namespace |
| Drift detection | Argo CD self-healing from Git |
| Immutable tags | CI rejects latest image tags and HEAD revisions |
| Cluster portability | Same chart works on EKS and OpenShift (openshift.enabled) |
On EKS, security relies on pod-level securityContext — which any chart consumer can override. On OpenShift, SecurityContextConstraints (SCC) enforce policy at admission and cannot be bypassed.
| Concern | EKS | OpenShift |
|---|---|---|
| Root enforcement | Pod spec field (overridable) | SCC (mandatory) |
| UID | Must specify runAsUser: 1000 |
Random UID assigned by SCC |
| Capabilities | Must write drop: [ALL] |
Dropped by default |
| Trust boundary | The pod spec | The cluster admission controller |
When openshift.enabled=true, pod-level securityContext is omitted to avoid conflicts with SCC. OpenShift exposure uses a TLS Route; the chart rejects Ingress manifests and Route policies that allow clear-text HTTP. Service-account tokens are disabled by default and must be explicitly enabled only for workloads that call the Kubernetes API.
Prometheus and Grafana are deployed as Argo CD-managed add-ons with a pre-built Platform App Overview dashboard covering CPU, memory, request rate, and pod status across all environments.
| Component | Data source | How it's discovered |
|---|---|---|
| Prometheus | kube-prometheus-stack | ServiceMonitor with label app.kubernetes.io/managed-by: platform |
| Grafana | Prometheus | Dashboard ConfigMap auto-loaded via provider config |
| Metrics | kube-state-metrics + cAdvisor | Default kube-prometheus-stack scrape configs |
| App metrics | /metrics endpoint |
ServiceMonitor template in the Helm chart (enabled by default) |
Every app deployed through the platform contract automatically gets a ServiceMonitor — teams don't need to configure scraping.
| Decision | Why |
|---|---|
| Argo CD over Flux | Already present in repo; single controller avoids drift between reconcilers |
| Helm as the contract format | Mature, lintable, env-overridable values; app teams already know it |
| Single chart promoted through envs | One chart + three values files = stable packaging, explicit promotion |
| One chart with an OpenShift mode | Keeps the developer experience consistent while respecting SCC and Route differences |
| GitOps for steady state | Makes desired state reviewable, auditable, and self-healing; direct cluster changes are limited to bootstrap and incident response |
| Secure defaults with explicit opt-in | Token mounting, external exposure, and elevated privileges require deliberate configuration rather than convention |
| Controls at render and policy time | Helm provides fast feedback; OPA validates rendered manifests as a second line of defense |
| No ROSA Terraform module | The infrastructure provider is an implementation detail; the supported workload contract is the primary product |
The platform separates concerns: Terraform owns cloud infrastructure, Argo CD owns in-cluster desired state, and the Helm chart owns the tenant workload contract. This avoids competing controllers and makes operational ownership clear.
- Policy enforcement in the cluster: add Gatekeeper or Kyverno admission policies for required labels, approved registries, resource limits, and network-policy coverage. Keep CI policy checks as fast feedback.
- Supply-chain security: require signed images, generate SBOMs, scan images in CI and at admission, and define an exception workflow with expiry.
- Environment onboarding: add a self-service template that creates namespace configuration, Argo CD application definitions, ownership metadata, and baseline alerts from a single reviewed request.
- Progressive delivery: introduce automated promotion gates based on health, error rate, and latency, with controlled rollback through Argo Rollouts or an equivalent mechanism.
- Production observability: standardize structured logs, distributed tracing, service-level objectives, alert routing, and dashboards that map to tenant ownership.
- OpenShift validation: run the rendered chart against an OpenShift-compatible API validation environment in CI, including SCC and Route behavior, rather than relying solely on structural checks.
- Lifecycle management: define supported Kubernetes/OpenShift versions, add-ons upgrade cadence, backup/restore tests, and a documented deprecation policy for the chart contract.
Makefile # One-command setup: kind cluster, Argo CD, deploy, validate, clean
kind-config.yaml # Kind cluster configuration with port mappings
argocd/ # AppProjects, app-of-apps, ApplicationSets, config, bootstrap
infra/ # VPC, IAM, EKS (Terraform modules)
platform/ # Namespaces, quotas, network policies, add-ons, Grafana dashboards, env overrides
standardized-path/ # Golden path Helm chart (the tenant contract)
policy/ # OPA/Rego policies for EKS and OpenShift security validation
docs/ # Architecture, operations, tenant contract
All validation runs on push/PR. Run locally:
make validateIndividual checks:
make test # 28 unit tests across 7 suites
helm lint standardized-path/app -f platform/apps/dev/values.yaml
helm template test standardized-path/app | kubeconform -summary
helm template test standardized-path/app \
--set openshift.enabled=true \
--set openshift.route.enabled=true \
--set ingress.enabled=false \
| grep "kind: Route"