Convert the hand-written deployment.yaml into a Helm chart so the app can be installed,
upgraded, and rolled back as a single versioned unit — and so the hostname and credentials are
passed in at install time rather than baked into the manifest.
Step 1 — Create the chart skeleton
Create the directory structure by hand — no generated boilerplate needed.
mkdir -p helm/csharp-messages/templates
Create helm/csharp-messages/Chart.yaml:
apiVersion: v2name: csharp-messagesdescription: Helm chart for the csharp-messages ASP.NET Core apptype: applicationversion: 0.1.0appVersion: "latest"
A Helm chart is a directory with two required files (Chart.yaml, values.yaml) and a templates/
folder. Chart.yaml provides metadata; values.yaml provides the defaults that callers override.
values.yaml declares only the four things that vary between installations — image, connection
string, hostname, and issuer. Everything else (port numbers, label names, replica count) stays
hardcoded in the templates because it never changes.
Step 2 — Template deployment.yaml
Create helm/csharp-messages/templates/deployment.yaml by copying the existing manifest and
replacing the three variable parts with template expressions:
conditional {{- if .Values.postgresql.connectionString }}
The {{- if }} guard means the env var is omitted entirely when connectionString is empty —
the app then falls back to SQLite, exactly as it did before the database was provisioned.
Step 3 — Template service.yaml
Create helm/csharp-messages/templates/service.yaml — only the namespace is templated:
The cert-manager.io/cluster-issuer annotation tells cert-manager to request a certificate from
the letsencrypt-prod issuer when the Ingress object is created. Traefik reads the tls block and
terminates TLS using the certificate stored in tls-messages-app.
ingress.host is set at install time to a hostname in the wildcard DNS zone provisioned in Chapter
3 (*.{username}.labs.netrics.dev), so no additional DNS record is needed.
Step 5 — Verify the chart
Lint and render locally before touching the cluster.
helm lint checks syntax and best-practice rules. helm template renders the chart locally — the
output is plain YAML you can read and diff. Neither command contacts the cluster.
Step 6 — Install
Remove the existing raw deployment, then install the chart.
Wait for the rollout and open the app in the browser:
kubectl rollout status deployment/messages-app -n messages-app
Navigate to https://messages.<your-username>.labs.netrics.dev — cert-manager will issue a
certificate automatically; it usually takes 30–60 seconds on first install.
Verify the health endpoint:
curl https://messages.$DNS_ZONE/health
Explanation
helm install creates a named release (messages-app). Helm stores release metadata in a
Secret inside the namespace, which is how it tracks what is deployed for upgrades and rollbacks.
--create-namespace replaces the explicit Namespace object that was at the top of
deployment.yaml. The namespace is now owned by the release.
Passing the connection string via --set works for a workshop. In production, store it in a
Kubernetes Secret and reference it with valueFrom.secretKeyRef in the deployment template,
or use External Secrets Operator to sync it from Key Vault (see the Challenges chapter).
Complete files
helm/csharp-messages/Chart.yaml
apiVersion: v2name: csharp-messagesdescription: Helm chart for the csharp-messages ASP.NET Core apptype: applicationversion: 0.1.0appVersion: "latest"