kustomize-overlays

Master environment-specific Kubernetes configuration management using Kustomize overlays, strategic merge patches, and JSON patches for development, staging, and production environments.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "kustomize-overlays" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-kustomize-overlays

Kustomize Overlays

Master environment-specific Kubernetes configuration management using Kustomize overlays, strategic merge patches, and JSON patches for development, staging, and production environments.

Overview

Overlays enable environment-specific customization of Kubernetes resources without duplicating configuration. Each overlay references a base configuration and applies environment-specific patches, transformations, and resource adjustments.

Basic Overlay Structure

myapp/ ├── base/ │ ├── kustomization.yaml │ ├── deployment.yaml │ ├── service.yaml │ ├── configmap.yaml │ └── ingress.yaml └── overlays/ ├── development/ │ ├── kustomization.yaml │ ├── replica-patch.yaml │ └── namespace.yaml ├── staging/ │ ├── kustomization.yaml │ ├── replica-patch.yaml │ ├── resource-patch.yaml │ └── namespace.yaml └── production/ ├── kustomization.yaml ├── replica-patch.yaml ├── resource-patch.yaml ├── hpa.yaml └── namespace.yaml

Base Configuration

Base Kustomization

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization

metadata: name: myapp-base

Resources to include

resources:

  • deployment.yaml
  • service.yaml
  • configmap.yaml
  • ingress.yaml

Common labels applied to all resources

commonLabels: app: myapp managed-by: kustomize

Common annotations

commonAnnotations: version: "1.0.0" team: platform

Name prefix for all resources

namePrefix: myapp-

Default namespace (can be overridden in overlays)

namespace: default

Image transformations

images:

  • name: myapp newName: registry.example.com/myapp newTag: latest

Base Deployment

base/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 8080 name: http env: - name: LOG_LEVEL valueFrom: configMapKeyRef: name: config key: log-level resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m" livenessProbe: httpGet: path: /health port: http initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: http initialDelaySeconds: 5 periodSeconds: 5

Base Service

base/service.yaml

apiVersion: v1 kind: Service metadata: name: service spec: type: ClusterIP ports:

  • port: 80 targetPort: http protocol: TCP name: http selector: app: myapp

Base ConfigMap

base/configmap.yaml

apiVersion: v1 kind: ConfigMap metadata: name: config data: log-level: "info" cache-enabled: "true" timeout: "30"

Base Ingress

base/ingress.yaml

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress annotations: kubernetes.io/ingress.class: nginx spec: rules:

  • host: myapp.example.com http: paths:
    • path: / pathType: Prefix backend: service: name: myapp-service port: number: 80

Development Overlay

Development Kustomization

overlays/development/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization

Reference the base

resources:

  • ../../base
  • namespace.yaml

Override namespace

namespace: development

Development-specific labels

commonLabels: environment: development cost-center: engineering

Development-specific annotations

commonAnnotations: deployed-by: ci-cd environment: dev

Name suffix for development resources

nameSuffix: -dev

Image overrides for development

images:

  • name: myapp newName: registry.example.com/myapp newTag: dev-latest

ConfigMap overrides

configMapGenerator:

  • name: config behavior: merge literals:
    • log-level=debug
    • cache-enabled=false
    • debug-mode=true

Replica overrides

replicas:

  • name: myapp-deployment count: 1

Strategic merge patches

patches:

  • path: replica-patch.yaml target: kind: Deployment name: myapp-deployment

Inline patches

patchesStrategicMerge:

  • |- apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: spec: containers: - name: myapp env: - name: ENVIRONMENT value: development - name: DEBUG value: "true"

Development Namespace

overlays/development/namespace.yaml

apiVersion: v1 kind: Namespace metadata: name: development labels: environment: development team: platform

Development Replica Patch

overlays/development/replica-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: replicas: 1 template: spec: containers: - name: myapp resources: requests: memory: "64Mi" cpu: "50m" limits: memory: "128Mi" cpu: "100m"

Staging Overlay

Staging Kustomization

overlays/staging/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization

resources:

  • ../../base
  • namespace.yaml

namespace: staging

commonLabels: environment: staging cost-center: engineering

commonAnnotations: deployed-by: ci-cd environment: staging

nameSuffix: -staging

images:

  • name: myapp newName: registry.example.com/myapp newTag: staging-v1.2.3

configMapGenerator:

  • name: config behavior: merge literals:
    • log-level=info
    • cache-enabled=true
    • cache-ttl=300

replicas:

  • name: myapp-deployment count: 2

patches:

  • path: replica-patch.yaml target: kind: Deployment name: myapp-deployment
  • path: resource-patch.yaml target: kind: Deployment name: myapp-deployment

patchesStrategicMerge:

  • |- apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080" spec: containers: - name: myapp env: - name: ENVIRONMENT value: staging - name: METRICS_ENABLED value: "true" affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname

Staging Replica Patch

overlays/staging/replica-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0

Staging Resource Patch

overlays/staging/resource-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: spec: containers: - name: myapp resources: requests: memory: "256Mi" cpu: "200m" limits: memory: "512Mi" cpu: "500m"

Production Overlay

Production Kustomization

overlays/production/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization

resources:

  • ../../base
  • namespace.yaml
  • hpa.yaml
  • pdb.yaml
  • network-policy.yaml

namespace: production

commonLabels: environment: production cost-center: product compliance: pci

commonAnnotations: deployed-by: ci-cd environment: production backup: "true"

nameSuffix: -prod

images:

  • name: myapp newName: registry.example.com/myapp newTag: v1.2.3 digest: sha256:abc123...

configMapGenerator:

  • name: config behavior: merge literals:
    • log-level=warn
    • cache-enabled=true
    • cache-ttl=600
    • rate-limit-enabled=true

replicas:

  • name: myapp-deployment count: 5

patches:

  • path: replica-patch.yaml target: kind: Deployment name: myapp-deployment
  • path: resource-patch.yaml target: kind: Deployment name: myapp-deployment
  • path: security-patch.yaml target: kind: Deployment name: myapp-deployment

patchesStrategicMerge:

  • |- apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080" vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "myapp" spec: containers: - name: myapp env: - name: ENVIRONMENT value: production - name: METRICS_ENABLED value: "true" - name: TRACING_ENABLED value: "true" affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - myapp topologyKey: kubernetes.io/hostname nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node.kubernetes.io/instance-type operator: In values: - m5.xlarge - m5.2xlarge

patchesJson6902:

  • target: group: networking.k8s.io version: v1 kind: Ingress name: myapp-ingress patch: |-
    • op: replace path: /spec/rules/0/host value: myapp.production.example.com
    • op: add path: /metadata/annotations/cert-manager.io~1cluster-issuer value: letsencrypt-prod
    • op: add path: /spec/tls value:
      • hosts:
        • myapp.production.example.com secretName: myapp-tls

Production Replica Patch

overlays/production/replica-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: replicas: 5 strategy: type: RollingUpdate rollingUpdate: maxSurge: 2 maxUnavailable: 0 minReadySeconds: 30

Production Resource Patch

overlays/production/resource-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: spec: containers: - name: myapp resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "1Gi" cpu: "1000m"

Production Security Patch

overlays/production/security-patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: spec: securityContext: runAsNonRoot: true runAsUser: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: myapp securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /app/cache volumes: - name: tmp emptyDir: {} - name: cache emptyDir: {}

Production HPA

overlays/production/hpa.yaml

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: myapp-hpa-prod spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: myapp-deployment-prod minReplicas: 5 maxReplicas: 20 metrics:

  • type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
  • type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 behavior: scaleDown: stabilizationWindowSeconds: 300 policies:
    • type: Percent value: 50 periodSeconds: 60 scaleUp: stabilizationWindowSeconds: 60 policies:
    • type: Percent value: 100 periodSeconds: 30
    • type: Pods value: 2 periodSeconds: 30 selectPolicy: Max

Production PDB

overlays/production/pdb.yaml

apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: myapp-pdb-prod spec: minAvailable: 3 selector: matchLabels: app: myapp environment: production

Production Network Policy

overlays/production/network-policy.yaml

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: myapp-network-policy-prod spec: podSelector: matchLabels: app: myapp environment: production policyTypes:

  • Ingress
  • Egress ingress:
  • from:
    • namespaceSelector: matchLabels: name: ingress-nginx
    • podSelector: matchLabels: app: prometheus ports:
    • protocol: TCP port: 8080 egress:
  • to:
    • namespaceSelector: matchLabels: name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports:
    • protocol: UDP port: 53
  • to:
    • podSelector: matchLabels: app: database ports:
    • protocol: TCP port: 5432

JSON Patch Examples

Replace Operations

patchesJson6902:

  • target: group: apps version: v1 kind: Deployment name: myapp-deployment patch: |-
    • op: replace path: /spec/replicas value: 10
    • op: replace path: /spec/template/spec/containers/0/image value: registry.example.com/myapp:v2.0.0

Add Operations

patchesJson6902:

  • target: group: apps version: v1 kind: Deployment name: myapp-deployment patch: |-
    • op: add path: /spec/template/spec/containers/0/env/- value: name: NEW_FEATURE_FLAG value: "true"
    • op: add path: /spec/template/metadata/annotations/sidecar.istio.io~1inject value: "true"

Remove Operations

patchesJson6902:

  • target: group: apps version: v1 kind: Deployment name: myapp-deployment patch: |-
    • op: remove path: /spec/template/spec/containers/0/env/2
    • op: remove path: /spec/template/metadata/annotations/deprecated-annotation

Advanced Patch Techniques

Conditional Patches

overlays/production/kustomization.yaml

patches:

  • target: kind: Deployment labelSelector: "tier=frontend" patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: not-used spec: template: spec: containers: - name: myapp resources: limits: memory: "2Gi"

Multi-Resource Patches

patches:

  • target: kind: Deployment|StatefulSet name: myapp-.* patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: not-used annotations: monitoring: "enabled"

Patch with Options

patches:

  • path: cpu-patch.yaml target: kind: Deployment options: allowNameChange: true allowKindChange: false

Multi-Environment Configuration

Region-Specific Overlays

overlays/ ├── us-east-1/ │ ├── development/ │ ├── staging/ │ └── production/ └── eu-west-1/ ├── development/ ├── staging/ └── production/

Regional Production Overlay

overlays/us-east-1/production/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization

resources:

  • ../../../overlays/production

commonLabels: region: us-east-1

configMapGenerator:

patchesStrategicMerge:

  • |- apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/region operator: In values: - us-east-1

When to Use This Skill

Use the kustomize-overlays skill when you need to:

  • Manage multiple environments (dev, staging, production) with different configurations

  • Apply environment-specific patches to base Kubernetes resources

  • Override resource limits, replicas, or environment variables per environment

  • Maintain a single source of truth with environment-specific variations

  • Apply strategic merge patches or JSON patches to resources

  • Manage region-specific or tenant-specific configurations

  • Implement progressive delivery with canary or blue-green deployments

  • Apply security policies and network policies per environment

  • Configure autoscaling differently across environments

  • Manage image tags and versions across multiple environments

  • Apply conditional patches based on labels or resource types

  • Implement cost optimization by varying resources per environment

  • Configure monitoring and observability settings per environment

  • Manage ingress rules and certificates per environment

  • Apply compliance and regulatory requirements to specific environments

Best Practices

  • Keep base configurations minimal and environment-agnostic

  • Use strategic merge patches for simple modifications

  • Use JSON patches for precise, surgical changes

  • Organize overlays by environment, then by region if needed

  • Use commonLabels to track resources by environment

  • Apply nameSuffix or namePrefix to avoid resource conflicts

  • Pin image tags with digests in production overlays

  • Use configMapGenerator with behavior: merge to override specific keys

  • Test overlay output with kustomize build before applying

  • Use kustomize edit commands for programmatic updates

  • Leverage replicas field for quick replica count overrides

  • Apply security contexts progressively from dev to production

  • Use HPA in production, fixed replicas in development

  • Document patch rationale in comments within kustomization.yaml

  • Use version control to track overlay changes over time

  • Validate patches don't inadvertently remove critical settings

  • Use namespace field consistently across all overlays

  • Apply resource quotas and limits progressively

  • Use podDisruptionBudgets only in production environments

  • Test disaster recovery by applying production overlays to staging

  • Use labelSelector in patches for conditional application

  • Avoid hardcoding environment-specific values in base

  • Use generators for ConfigMaps and Secrets instead of static files

  • Apply network policies in production for security

  • Use affinity rules to distribute pods across nodes in production

Common Pitfalls

  • Duplicating entire resources in overlays instead of patching

  • Hardcoding environment-specific values in base configurations

  • Not using namespace field consistently across overlays

  • Forgetting to update image tags in production overlays

  • Over-patching - making too many changes in overlays

  • Not testing overlay output before applying to clusters

  • Using incorrect patch paths in JSON patches

  • Forgetting to escape tildes in JSON patch paths

  • Not using behavior: merge with configMapGenerator

  • Applying production-grade resources to development environments

  • Not validating that patches actually apply successfully

  • Using replicas in kustomization.yaml and deployment patches simultaneously

  • Not organizing overlays in a clear directory structure

  • Forgetting to add new resources to kustomization.yaml

  • Using absolute paths instead of relative paths in resources

  • Not documenting why specific patches are necessary

  • Applying breaking patches without testing

  • Not using version control for overlay changes

  • Forgetting to apply security contexts in production

  • Using mutable image tags in production overlays

  • Not considering resource consumption differences across environments

  • Applying patches that conflict with each other

  • Not validating JSON patch syntax before committing

  • Using strategic merge for complex changes better suited to JSON patch

  • Not cleaning up obsolete patches and overlay resources

  • Forgetting to update overlay references when restructuring

  • Not using labelSelector for conditional patches

  • Hardcoding secrets in overlays instead of using external secret management

  • Not testing overlay changes in lower environments first

  • Applying network policies without understanding connectivity requirements

Resources

  • Kustomize Official Documentation

  • Kubernetes SIG-CLI Kustomize

  • Kustomize Feature List

  • Strategic Merge Patch

  • JSON Patch RFC 6902

  • Kubectl Apply with Kustomize

  • Kustomize Best Practices

  • GitOps with Kustomize

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

typescript-type-system

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

typescript-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

c-systems-programming

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

cpp-templates-metaprogramming

No summary provided by upstream source.

Repository SourceNeeds Review