Kubernetes
Helm charts
Ingress resources
Cloud computing
Container orchestration

Helm charts and Ingress resources

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Helm and Kubernetes Ingress are commonly used together, but many production issues come from unclear boundaries between chart templating, controller behavior, and environment-specific ingress class configuration. Helm is responsible for rendering Kubernetes manifests from templates and values. Ingress behavior is then enforced by whichever controller is installed in the cluster (NGINX, GCE, Traefik, etc.). This article explains how to model ingress resources in Helm charts safely, how to parameterize values for multiple environments, and how to validate rendered output before deployment.

Model Ingress as Optional Chart Output

Ingress should usually be toggleable via values so the same chart works in internal, staging, and external environments.

yaml
1# values.yaml
2ingress:
3  enabled: true
4  className: nginx
5  host: app.example.com
6  path: /
7  pathType: Prefix
8  tls:
9    enabled: true
10    secretName: app-tls

Template pattern:

yaml
1{{- if .Values.ingress.enabled }}
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5  name: {{ include "myapp.fullname" . }}
6spec:
7  ingressClassName: {{ .Values.ingress.className | quote }}
8  rules:
9  - host: {{ .Values.ingress.host | quote }}
10    http:
11      paths:
12      - path: {{ .Values.ingress.path | quote }}
13        pathType: {{ .Values.ingress.pathType }}
14        backend:
15          service:
16            name: {{ include "myapp.fullname" . }}
17            port:
18              number: 80
19{{- end }}

This keeps chart behavior explicit and portable.

Separate Controller-Specific Annotations

Ingress annotations are controller-specific. Do not assume annotations for NGINX apply on GCE ingress.

yaml
1metadata:
2  annotations:
3    nginx.ingress.kubernetes.io/proxy-body-size: "20m"
4    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"

A clean approach is values-driven annotation maps:

yaml
ingress:
  annotations: {}
yaml
metadata:
  annotations:
{{- toYaml .Values.ingress.annotations | nindent 4 }}

Then each environment file can set the right keys for its controller.

Validate Rendered Manifests Before Apply

Many ingress failures are discovered only after deployment. Validate earlier.

bash
helm lint ./chart
helm template myapp ./chart -f values-prod.yaml > rendered.yaml
kubectl apply --dry-run=server -f rendered.yaml

Also verify controller and class availability in target cluster:

bash
kubectl get ingressclass
kubectl get pods -A | grep -i ingress

If no matching controller is installed for your ingressClassName, routing will not activate even if the resource is created.

Prefer Environment-Specific Values Files

Keep base chart generic and move public hostnames, TLS secrets, and annotation tuning into overlay values files.

bash
helm upgrade --install myapp ./chart \
  -f values.yaml \
  -f values-prod.yaml

This avoids hard-coded production settings in shared templates and reduces accidental drift between environments.

Practical Verification Workflow

A strong way to avoid regressions is to validate changes in three stages: baseline, targeted change, and repeatability. First, capture a baseline command/output before applying fixes so you can prove improvement. Second, apply one focused change at a time, then rerun the exact same check to confirm causality. Third, rerun the validation multiple times (or with nearby input variants) to ensure behavior is stable and not a one-off pass.

A simple validation template:

bash
1# 1) capture baseline behavior
2./run_case.sh > before.txt
3
4# 2) apply one targeted fix
5# edit code/config based on this article
6
7# 3) validate after change
8./run_case.sh > after.txt
9diff -u before.txt after.txt

If your stack has tests, add at least one regression test that fails before the fix and passes after it. This turns troubleshooting knowledge into durable protection against future changes. In team environments, including the exact commands used for verification in pull requests or runbooks makes results reproducible across machines and CI.

Operational Checklist for Production Use

Before shipping a fix or optimization, confirm environment parity and observability. Verify toolchain/runtime versions, capture key metrics, and define rollback criteria. A technically correct local fix can still fail in production if infrastructure assumptions differ.

bash
1# Example pre-release checks
2./lint.sh
3./test.sh
4./smoke_test.sh

A minimal release checklist usually includes: compatible dependency versions, representative test coverage, explicit monitoring signals, and a rollback plan. This discipline reduces the chance that a local solution introduces new issues under real traffic or larger datasets.

Common Pitfalls

  • Treating ingress annotations as universal even though they are controller-specific.
  • Hard-coding hostnames and TLS settings directly in templates.
  • Omitting ingressClassName in clusters with multiple ingress controllers.
  • Deploying without rendering and validating manifests first.
  • Assuming an Ingress resource guarantees routing when no compatible controller is running.

Summary

Use Helm to template Ingress resources as optional, values-driven outputs, and keep controller-specific behavior in environment configuration. Validate with helm lint, helm template, and server dry-runs before rollout. This pattern makes ingress management predictable across clusters and avoids the most common controller mismatch errors.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.