Namespace Templates: Instant Envs in K8s
Create production-ready namespace templates for instant environment provisioning. One command deploys namespace, RBAC, quotas, network policies, and monitoring.
π‘ Quick Answer: Create a namespace template (Helm chart or Kustomize base) that provisions a complete environment in one command: namespace + ResourceQuota + LimitRange + RBAC + NetworkPolicy + monitoring ServiceMonitor. New teams/apps get production-ready isolation in seconds, not days.
The Problem
βKubernetes is too complexβ usually means βI have to set up everything from scratch every time.β Thatβs only true if you havenβt built templates. Once you have a namespace template, spinning up a new environment is one command β and it comes with security, quotas, and monitoring built in.
flowchart LR
CMD["helm install<br/>my-team team-ns/"] --> NS["Namespace"]
CMD --> QUOTA["ResourceQuota<br/>CPU: 8, RAM: 16Gi"]
CMD --> RBAC["RoleBindings<br/>edit + view"]
CMD --> NP["NetworkPolicy<br/>default-deny"]
CMD --> MON["ServiceMonitor<br/>+ AlertRules"]
CMD --> LR["LimitRange<br/>defaults"]The Solution
Helm Chart: Namespace Template
namespace-template/
βββ Chart.yaml
βββ values.yaml
βββ templates/
βββ namespace.yaml
βββ resourcequota.yaml
βββ limitrange.yaml
βββ rbac.yaml
βββ networkpolicy.yaml
βββ monitoring.yamlChart.yaml:
apiVersion: v2
name: namespace-template
description: Production-ready namespace in one command
version: 1.0.0values.yaml:
team: ""
environment: dev
owner: ""
quota:
cpu: "8"
memory: 16Gi
pods: "50"
storage: 100Gi
limits:
defaultCpu: 500m
defaultMemory: 512Mi
maxCpu: "4"
maxMemory: 8Gi
rbac:
editGroup: "" # OIDC group with edit access
viewGroup: "" # OIDC group with read-only
networkPolicy:
allowDNS: true
allowIntraNamespace: true
allowIngress: true
egressCIDRs: [] # External CIDRs to allowtemplates/namespace.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.team }}-{{ .Values.environment }}
labels:
team: {{ .Values.team }}
environment: {{ .Values.environment }}
owner: {{ .Values.owner }}
pod-security.kubernetes.io/enforce: restrictedtemplates/resourcequota.yaml:
apiVersion: v1
kind: ResourceQuota
metadata:
name: default
namespace: {{ .Values.team }}-{{ .Values.environment }}
spec:
hard:
requests.cpu: {{ .Values.quota.cpu }}
requests.memory: {{ .Values.quota.memory }}
pods: {{ .Values.quota.pods }}
requests.storage: {{ .Values.quota.storage }}templates/rbac.yaml:
{{- if .Values.rbac.editGroup }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-edit
namespace: {{ .Values.team }}-{{ .Values.environment }}
subjects:
- kind: Group
name: {{ .Values.rbac.editGroup }}
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: edit
apiGroup: rbac.authorization.k8s.io
{{- end }}templates/networkpolicy.yaml:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: {{ .Values.team }}-{{ .Values.environment }}
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-baseline
namespace: {{ .Values.team }}-{{ .Values.environment }}
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector: {}
egress:
- to:
- podSelector: {}
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDPOne Command to Create an Environment
# New team onboarding β takes 5 seconds
helm install payments namespace-template/ \
--set team=payments \
--set environment=dev \
--set owner=alice@example.com \
--set rbac.editGroup=team-payments \
--set quota.cpu=16 \
--set quota.memory=32Gi
# Verify everything was created
kubectl get all,quota,limitrange,netpol -n payments-dev
# Need a staging environment? Same template, different values:
helm install payments-staging namespace-template/ \
--set team=payments \
--set environment=staging \
--set owner=alice@example.com \
--set rbac.editGroup=team-payments \
--set quota.cpu=8GitOps: ArgoCD ApplicationSet
# Auto-create namespaces from a list in Git
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: team-namespaces
spec:
generators:
- git:
repoURL: https://github.com/org/platform-config
revision: main
files:
- path: "teams/*/config.yaml"
template:
metadata:
name: "ns-{{team}}-{{environment}}"
spec:
source:
repoURL: https://github.com/org/namespace-template
targetRevision: main
helm:
valueFiles:
- "teams/{{team}}/config.yaml"
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: trueCommon Issues
| Issue | Cause | Fix |
|---|---|---|
| Team needs more quota | Default too restrictive | Override with --set quota.cpu=32 |
| Pods canβt reach external APIs | NetworkPolicy egress blocked | Add egressCIDRs for required endpoints |
| RBAC group not working | OIDC group name mismatch | Verify group claim matches IdP config |
Best Practices
- Template everything β never create namespaces manually
- GitOps the templates β ArgoCD ApplicationSet for automatic provisioning
- Start restrictive β default-deny network + restricted PSA, open as needed
- Version your templates β semver the Helm chart, upgrade teams incrementally
- Self-service portal β Backstage or internal UI that calls
helm installbehind the scenes
Key Takeaways
- One Helm chart = complete production-ready environment in seconds
- Namespace templates eliminate the βK8s is complexβ complaint for day-to-day work
- GitOps + ApplicationSet = fully automated multi-team provisioning
- The initial template investment pays off on every subsequent environment

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
