Part 2: Creating Your First Chart

Series Navigation: ← Part 1: Introduction and Installation | Back to Series Overview | Part 3: Advanced Templates and Values β†’

Introduction

In Part 1, we installed Helm and explored existing Charts. Now it's time to create our own. In this article, I'll walk you through building a Helm Chart for a TypeScript Node.js APIβ€”the kind of application I deploy regularly.

Creating your first Chart might seem daunting, but I've learned that starting with a simple structure and iterating is the best approach. We'll build a complete Chart for a REST API, including Deployment, Service, ConfigMap, and basic health checks.

The TypeScript Application

Let me show you the application we'll be deploying. This is a simple Express API I use as a template for microservices:

Project Structure

typescript-api/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ server.ts
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── health.ts
β”‚   └── config/
β”‚       └── index.ts
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ Dockerfile
└── helm-chart/          # We'll create this

The Application Code

src/server.ts:

src/routes/health.ts:

src/config/index.ts:

Dockerfile:

Creating the Chart

Now let's create a Helm Chart for this application.

Initialize Chart Structure

Helm's create command generates a complete Chart, but I prefer starting minimal and adding what I need. Let me show you my approach.

Chart.yaml - Chart Metadata

helm-chart/Chart.yaml:

Key points from my experience:

  • version: Chart version - increment when you change templates

  • appVersion: Application version - update when you release new code

  • type: Use application for deployable apps, library for shared templates

  • kubeVersion: Helps prevent deployment to incompatible clusters

values.yaml - Default Configuration

helm-chart/values.yaml:

This values file includes everything I typically need. You can start simpler and add sections as needed.

Template Helpers

helm-chart/templates/_helpers.tpl:

Helper templates reduce repetition and make charts maintainable. I use these patterns in every Chart I create.

Deployment Template

helm-chart/templates/deployment.yaml:

Key features I always include:

  • ConfigMap checksum annotation to trigger rolling updates on config changes

  • Separate security contexts for pod and container

  • Health probes using the /health endpoints

  • Volume mount for /tmp since we use read-only root filesystem

  • Environment variables from both values and ConfigMap

Service Template

helm-chart/templates/service.yaml:

Simple and straightforwardβ€”exposes the Deployment on the specified port.

ConfigMap Template

helm-chart/templates/configmap.yaml:

This ConfigMap allows injecting configuration without rebuilding the image.

ServiceAccount Template

helm-chart/templates/serviceaccount.yaml:

Ingress Template (Optional)

helm-chart/templates/ingress.yaml:

HorizontalPodAutoscaler Template (Optional)

helm-chart/templates/hpa.yaml:

NOTES.txt - Post-Install Instructions

helm-chart/templates/NOTES.txt:

This displays helpful information after installation.

Testing the Chart

Now let's validate and test our Chart.

Lint the Chart

Dry Run Installation

This shows the rendered Kubernetes manifests without applying them.

Template Rendering

Install the Chart

Verify Installation

Environment-Specific Values

I maintain separate values files for each environment:

values-dev.yaml:

values-prod.yaml:

Deploy with environment-specific values:

Upgrading and Rolling Back

Upgrade a Release

Rollback a Release

Debugging Chart Issues

Common issues I've encountered and how to debug them:

Templates Not Rendering

Failed Installation

Value Not Applied

Best Practices from Experience

Here are patterns I follow for every Chart:

  1. Always use helper templates for names and labelsβ€”ensures consistency

  2. Include health probesβ€”critical for zero-downtime deployments

  3. Set resource limitsβ€”prevents resource exhaustion

  4. Use security contextsβ€”follow security best practices

  5. ConfigMap checksumsβ€”trigger pod restarts on config changes

  6. Separate environment valuesβ€”maintain clarity between dev/staging/prod

  7. Document with NOTES.txtβ€”help users access the application

  8. Test with helm lint and helm templateβ€”catch errors early

  9. Version your chartsβ€”increment Chart version with each change

  10. Use .helmignoreβ€”exclude unnecessary files from packaged charts

What's Next?

We've created a complete, production-ready Helm Chart for a TypeScript application. In Part 3, we'll dive deeper into advanced templating:

  • Template functions and pipelines

  • Complex conditional logic

  • Named templates and includes

  • Range loops and data structures

  • Advanced value manipulation

  • Creating reusable chart libraries


Series Navigation: ← Part 1: Introduction and Installation | Back to Series Overview | Part 3: Advanced Templates and Values β†’

Key Takeaways

  • βœ… Charts follow a standard structure with templates, values, and helpers

  • βœ… Helper templates reduce repetition and ensure consistency

  • βœ… ConfigMap checksums trigger rolling updates on config changes

  • βœ… Always include health probes and security contexts

  • βœ… Environment-specific values files enable multi-environment deployments

  • βœ… Testing with lint, template, and dry-run catches errors before deployment

  • βœ… Helm makes upgrades and rollbacks simple and reliable

Last updated