This chapter covers Helm charts on Google Kubernetes Engine (GKE), a critical skill for the ACE exam under Domain 3: Deploy Implement, Objective 3.2 (Deploying applications on GKE). Helm is the package manager for Kubernetes, enabling you to define, install, and upgrade complex applications as a single unit. Expect 1-2 questions directly referencing Helm on the ACE exam, plus indirect questions about application deployment patterns that assume Helm knowledge. Mastering Helm charts will also streamline your workflow in production environments and during the performance-based portion of the exam.
Jump to a section
Imagine you are a construction foreman who needs to build identical houses in 50 different neighborhoods. Each house needs the same foundation, framing, plumbing, and electrical layout, but each neighborhood has different soil types, local building codes, and utility hookups. Instead of drawing blueprints from scratch for every house, you create a master blueprint package (a Helm chart) that includes all standard specifications: floor plan, wiring diagram, pipe runs, and material list. The blueprint also has placeholders—like 'soil type' or 'local code version'—that you fill in with neighborhood-specific values (a values.yaml file). When you hand the blueprint to a crew, they use it to build the house exactly as specified, but adapted to the local conditions. If you need to upgrade the plumbing in all houses, you update the master blueprint once, and every future build automatically includes the new pipes. Helm charts work the same way: they package Kubernetes resources (Deployments, Services, ConfigMaps) as reusable templates with parameters. You deploy the chart with different values for each environment (dev, staging, prod), and Helm renders the templates into final YAML files that kubectl applies to the cluster. Updating the chart version upgrades all deployments that use it.
What is Helm and Why Does It Exist?
Helm is the Kubernetes package manager, analogous to apt for Debian or yum for RHEL, but for Kubernetes resources. It addresses the problem of managing multiple interrelated Kubernetes objects (Deployments, Services, ConfigMaps, Secrets, etc.) that form an application. Without Helm, you would need to write and maintain dozens of YAML files, track versions manually, and replicate configurations across environments. Helm packages these resources into a chart—a collection of files that describe a related set of Kubernetes resources. A chart can be installed, upgraded, rolled back, and deleted as a single unit. Helm also provides dependency management, so you can include other charts (e.g., a database) as subcharts.
How Helm Works Internally
Helm operates in two modes: Helm v2 (client-server with Tiller) and Helm v3 (client-only, no Tiller). The ACE exam focuses on Helm v3, which is the current standard. In Helm v3, the helm CLI communicates directly with the Kubernetes API server. When you run helm install, it takes the chart (a directory or packaged .tgz file), reads the values you provide (defaults from values.yaml plus overrides via --set or a custom values file), and renders Go templates in the chart templates into final Kubernetes YAML manifests. These manifests are then sent to the Kubernetes API server via kubectl apply-like functionality. Helm stores release information (the deployed chart, its values, and its status) in Secrets in the same namespace as the release. This allows helm list, helm history, helm rollback, and helm upgrade to work.
Key Components of a Helm Chart
A Helm chart has a standard directory structure:
mychart/
Chart.yaml # Metadata: name, version, description, dependencies
values.yaml # Default configuration values
charts/ # Subcharts (dependencies)
templates/ # Go template files that generate Kubernetes manifests
templates/NOTES.txt # Optional: usage notes printed after install
crds/ # Custom Resource Definitions (installed first)Chart.yaml: Contains the chart name, version (semver), appVersion (the application version), and dependencies (a list of other charts with repository URLs and version constraints).
values.yaml: Defines default values in YAML format. Users override these via --values myvals.yaml or --set key=value. Values are accessed in templates using .Values.key.
templates/: Contains Go template files (.yaml or .tpl) that use Helm's built-in functions and Sprig template library. Templates can include conditionals ({{ if .Values.enabled }}), loops, and variable assignments.
charts/: Stores dependent charts as subdirectories or packaged .tgz files. Dependencies can also be fetched from a repository using helm dependency update.
crds/: Contains Custom Resource Definitions (CRDs) that are installed before the templates, ensuring CRD types exist before creating custom resources.
Helm Repositories
Charts are distributed via Helm repositories, which are HTTP servers that host an index.yaml file (the repository index) and the packaged chart files. The index file lists all available chart versions, their URLs, and checksums. Common public repositories include:
Bitnami (https://charts.bitnami.com/bitnami)
Helm Stable (https://kubernetes-charts.storage.googleapis.com) — deprecated, now part of Artifact Hub
Artifact Hub (https://artifacthub.io) — a central search engine for Helm charts and other Kubernetes packages
To add a repository:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo updateThe Helm Install and Upgrade Process
1. helm install [release-name] [chart] --values custom-values.yaml
- Helm reads the chart directory or downloads the packaged chart from a repository.
- It merges the default values from values.yaml with the user-provided overrides.
- It renders all templates using the merged values.
- It creates a release Secret in the target namespace (default: default).
- It applies the rendered manifests to the cluster in a specific order: Namespaces, Secrets, ConfigMaps, PersistentVolumeClaims, ServiceAccounts, RoleBindings, Services, Deployments, StatefulSets, etc. (Helm follows the typical Kubernetes resource dependency order).
- It prints the NOTES.txt content if present.
2. helm upgrade [release-name] [chart] --values custom-values.yaml
- Helm compares the new chart's rendered manifests with the previous release's manifests (stored in the release Secret).
- It computes a three-way strategic merge patch: the old configuration, the new configuration, and the live state in the cluster.
- It applies only the changes needed (additions, updates, deletions).
- It increments the release revision number.
- If the upgrade fails, you can roll back with helm rollback [release-name] [revision].
Values Precedence
Helm uses a clear precedence order for values (from highest to lowest):
--set flags (multiple --set flags are merged left-to-right)
--values file (or -f), with later files overriding earlier ones
Values from the parent chart's values.yaml (if installing a dependency as a subchart)
The chart's own values.yaml
Common Helm Commands for ACE
| Command | Purpose |
|---------|---------|
| helm create <name> | Scaffold a new chart directory |
| helm package <chart-dir> | Package a chart into a .tgz file |
| helm install <release> <chart> | Install a chart |
| helm upgrade <release> <chart> | Upgrade a release |
| helm rollback <release> <revision> | Roll back to a previous revision |
| helm list | List releases (add -A for all namespaces) |
| helm history <release> | Show revision history |
| helm uninstall <release> | Delete a release (and its resources) |
| helm repo add/update/list | Manage repositories |
| helm dependency update | Download chart dependencies |
| helm template <release> <chart> | Render templates locally without installing |
| helm get values <release> | View the values used for a release |
| helm get manifest <release> | View the rendered YAML manifests |
Helm on GKE: Integration with Google Cloud
GKE does not require any special setup for Helm. You can use Helm v3 with any GKE cluster (standard or Autopilot) as long as you have kubectl configured with appropriate credentials. However, there are GKE-specific considerations:
IAM permissions: To install charts that create cluster-scoped resources (e.g., ClusterRole, Namespace), you need container.clusterRoleBindings.create and similar permissions. For namespace-scoped resources, you need container.deployments.create etc. The ACE exam may test that you need the Kubernetes Engine Cluster Admin role or a custom role with these permissions.
Workload Identity: If your chart creates Pods that access Google Cloud APIs (e.g., Cloud Storage), you should configure Workload Identity. This is done by annotating the Kubernetes ServiceAccount with iam.gke.io/gcp-service-account. Your chart templates must include this annotation.
GKE Marketplace: Google Cloud Marketplace uses Helm charts under the hood. When you deploy an application from the Marketplace, it creates a Helm release in your cluster. You can manage these releases with helm list and helm upgrade.
Autopilot clusters: Helm works on Autopilot, but you must ensure your chart does not require privileged containers or host network access, as Autopilot restricts these.
Chart Dependencies and Subcharts
Charts can depend on other charts. Dependencies are declared in Chart.yaml:
dependencies:
- name: postgresql
version: "10.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabledAfter editing Chart.yaml, run:
helm dependency updateThis downloads the dependency into the charts/ directory and updates Chart.lock (a lock file for reproducible builds). Subchart values are accessed in templates via .Values.subchartname.key. Values for subcharts can be overridden in the parent chart's values.yaml under a key matching the subchart name:
postgresql:
enabled: true
postgresqlPassword: "mysecret"Best Practices for Helm Charts on GKE
Use `helm template` to validate your chart before installing: helm template myrelease ./mychart --debug.
Version your charts using semantic versioning in Chart.yaml. The ACE exam may ask about the version field vs appVersion.
Store chart packages in a container registry (e.g., Artifact Registry) using OCI-based Helm repositories. GKE supports pulling charts from Artifact Registry via helm pull oci://LOCATION-docker.pkg.dev/PROJECT/REPO/CHART:version.
Use `helm upgrade --install` to combine install and upgrade into one command. This creates the release if it doesn't exist, or upgrades it if it does.
Avoid storing secrets in `values.yaml`. Use external secret management (e.g., Google Cloud Secret Manager) and reference them via environment variables or CSI drivers. Helm supports .Values but those values are stored in the release Secret in plaintext.
Troubleshooting Helm on GKE
Release not found: Ensure you are in the correct namespace. Use helm list -A to see all releases.
Template rendering error: Run helm template with --debug to see the rendered output and identify syntax errors.
Resource already exists: Helm uses three-way merge, but if a resource was created outside Helm, helm upgrade may fail. Use helm install with --replace (not recommended) or delete the resource manually.
Permission denied: Check your GKE RBAC bindings. You may need to create a RoleBinding or ClusterRoleBinding for your user or service account.
Create a Helm Chart
Use `helm create mychart` to scaffold a new chart directory. This creates the standard structure: Chart.yaml, values.yaml, templates/, charts/, and .helmignore. Edit Chart.yaml to set the chart name, version (e.g., 0.1.0), and appVersion (e.g., 1.0.0). Modify values.yaml to define default configuration values for your application, such as image repository, tag, replica count, and service type. Create template files for each Kubernetes resource you need (Deployment, Service, ConfigMap, etc.) using Go template syntax. Use `{{ .Values.replicaCount }}` to reference values. Use `helm template myrelease ./mychart` to verify rendering.
Add a Helm Repository
If you want to install a chart from a repository (e.g., Bitnami), add the repository using `helm repo add bitnami https://charts.bitnami.com/bitnami`. Then run `helm repo update` to fetch the latest index. You can search for charts with `helm search repo bitnami`. For GKE, you might also add a private repository hosted in Artifact Registry using `helm repo add myrepo oci://us-central1-docker.pkg.dev/my-project/my-repo`.
Install the Chart
Run `helm install my-release bitnami/nginx --values custom-values.yaml --namespace my-namespace --create-namespace`. Helm will render the templates using the merged values, create the namespace if it doesn't exist, and apply the resources. The release name must be unique within the namespace. After installation, Helm prints the NOTES.txt content. Verify with `kubectl get all -n my-namespace` and `helm list -n my-namespace`.
Upgrade the Release
To update the application, modify your values file or chart, then run `helm upgrade my-release bitnami/nginx --values new-values.yaml`. Helm computes the diff between the current release, the new chart, and the live cluster state, and applies only the changes. It creates a new revision. If the upgrade fails, use `helm rollback my-release 1` to revert to the previous revision. Use `helm history my-release` to see revision numbers.
Roll Back a Release
If a deployment causes issues, roll back to a known good revision. First, list revisions with `helm history my-release`. Then run `helm rollback my-release <revision-number>`. Helm will reapply the manifests from that revision. The rollback creates a new revision (the old revision is not overwritten). You can also roll back to the previous revision using `helm rollback my-release (helm history my-release -o json | jq '.[-2].revision')`.
Enterprise Scenario 1: Microservices Deployment at Scale
A large e-commerce company runs 200+ microservices on a multi-tenant GKE cluster. Each microservice has its own Helm chart with common templates for Deployment, Service, HorizontalPodAutoscaler, and ServiceMonitor (for Prometheus). They maintain a central values repository (a Git repo) with environment-specific values files: dev-values.yaml, staging-values.yaml, and prod-values.yaml. The CI/CD pipeline (Cloud Build) runs helm template to validate changes, then helm upgrade --install to deploy to the appropriate namespace. They use Helm's dependency management to include a shared logging sidecar chart. Common problems: forgetting to run helm dependency update after changing dependencies, leading to stale subcharts. They mitigate this by running helm dependency build (which updates and packages) in the pipeline. Performance: with 200 releases, helm list can be slow; they use --max-col-width=0 for scriptable output and filter by namespace.
Enterprise Scenario 2: Third-Party Application Deployment
A healthcare startup uses GKE Marketplace to deploy a commercial PACS (Picture Archiving and Communication System) that comes as a Helm chart. The chart includes a PostgreSQL subchart (Bitnami), a custom application Deployment, and a ConfigMap for configuration. They override the PostgreSQL values to use a Cloud SQL proxy sidecar instead of a direct database connection. They store the chart in Artifact Registry as an OCI artifact for version control. During upgrades, they use helm get values to capture the current configuration before applying changes. A common issue: the Marketplace chart expects certain annotations for Workload Identity, which they must add via a custom values file. Misconfiguring the database connection string in values.yaml causes the application to fail to start. They use helm template with --debug to verify the rendered ConfigMap before applying.
Enterprise Scenario 3: GitOps with Helm and Config Sync
A financial services firm uses Config Sync (a Google Cloud service) to manage GKE clusters in a GitOps workflow. They store Helm charts in a Git repository and use Config Sync's Helm support (via source of truth) to sync the cluster state. Config Sync renders the Helm charts and applies them, ensuring the cluster matches the Git repo. They use Helm's --set parameters in the Config Sync configuration to inject environment-specific values. A common pitfall: Config Sync's Helm renderer does not support all Helm features (e.g., post-render hooks). They must test charts with helm template before committing. When misconfigured, Config Sync may delete resources that were created outside the chart (e.g., manually created Secrets). They mitigate this by using Helm's three-way merge and ensuring all resources are managed by Helm.
What the ACE Exam Tests on Helm Charts
The ACE exam (Objective 3.2: Deploying applications on GKE) tests Helm in the context of application deployment. Expect questions that require you to:
Identify the correct command to install, upgrade, or roll back a release. Common wrong answer: using kubectl apply with a chart directory (charts are not raw YAML).
Understand values precedence: The exam may ask which value takes effect when multiple --set and --values flags are used. Answer: --set overrides --values, and later --values files override earlier ones. The chart's values.yaml has the lowest precedence.
Distinguish between `version` and `appVersion`: The chart version (version) is used by Helm for release management; appVersion is informational (the application version). A wrong answer might claim they are the same.
Know the default namespace: If no --namespace flag is given, Helm installs into the default namespace. The exam may test that you must use --create-namespace to create a new namespace.
Recognize that Helm v3 does not use Tiller: A common distractor is mentioning Tiller in a Helm v3 context.
Understand that `helm rollback` creates a new revision: It does not revert to the exact previous revision number; it creates a new one with the old manifests.
Know that Helm stores release info in Secrets: In the same namespace as the release. The exam might ask where release metadata is stored.
Identify the correct repository URL for Bitnami: https://charts.bitnami.com/bitnami.
Understand that `helm template` does not contact the cluster: It only renders templates locally. Useful for CI/CD validation.
Common Wrong Answers and Why
Using `kubectl apply -f chart/`: Charts are not raw YAML; they are templates. You must use helm install or helm template first.
Claiming that `helm upgrade` always recreates all resources: Helm uses three-way merge and only applies changes. It does not recreate unchanged resources.
Thinking that `helm list` shows all releases across all namespaces by default: It only shows releases in the current namespace (from kubeconfig context). Use -A for all namespaces.
Confusing `helm install` with `helm create`: helm create scaffolds a new chart; helm install deploys it.
Believing that Helm charts are only for stateless applications: Helm works with StatefulSets, DaemonSets, and any Kubernetes resource.
Edge Cases the Exam Loves
Installing a chart without --namespace when the cluster has RBAC that restricts the default namespace.
Using helm upgrade --install for the first time: This works and creates the release if it doesn't exist.
Chart dependencies with condition field: If the condition is false, the subchart is not installed.
OCI-based registries: The exam may test that you can pull charts from Artifact Registry using oci:// URL.
Workload Identity integration: You must annotate the Kubernetes ServiceAccount with the correct annotation iam.gke.io/gcp-service-account.
Helm v3 is client-only; no Tiller server-side component.
Use `helm create <name>` to scaffold a new chart.
Values precedence: --set > --values file > chart's values.yaml.
Release metadata is stored in Secrets in the release namespace.
`helm template` renders templates locally without contacting the cluster.
`helm upgrade --install` creates or upgrades a release in one command.
Chart dependencies are declared in Chart.yaml and managed with `helm dependency update`.
On GKE, use `oci://` URLs to pull charts from Artifact Registry.
Workload Identity requires annotating the Kubernetes ServiceAccount with `iam.gke.io/gcp-service-account`.
Always use `--namespace` and `--create-namespace` when installing to a non-default namespace.
These come up on the exam all the time. Here's how to tell them apart.
Helm Charts
Package multiple resources into a single reusable unit.
Support templating and parameterization via values.yaml.
Provide versioning, rollback, and upgrade capabilities.
Manage dependencies (subcharts) automatically.
Require Helm CLI and chart repository knowledge.
Raw Kubernetes YAML Manifests
Each resource is a separate YAML file or combined in a single file.
No built-in templating; values are hardcoded or managed externally.
No native versioning or rollback; must use kubectl and Git.
No dependency management; must manually manage related resources.
Simple to debug and apply with kubectl apply -f.
Mistake
Helm v2 and v3 are interchangeable on GKE.
Correct
Helm v3 is the current standard and the only version supported on GKE. Helm v2 required a server-side component called Tiller, which is a security risk and is not used in v3. The ACE exam tests Helm v3.
Mistake
Helm charts can only be installed from public repositories.
Correct
Helm charts can be installed from local directories, packaged .tgz files, or OCI-compliant registries like Artifact Registry. You can also use private Helm repositories.
Mistake
`helm upgrade` always deletes and recreates all resources.
Correct
Helm v3 uses a three-way strategic merge patch—comparing the old manifest, new manifest, and live state. It only applies changes (additions, modifications, deletions) to resources that differ. Resources that remain unchanged are left untouched.
Mistake
The `appVersion` field in Chart.yaml controls the version of the application deployed.
Correct
`appVersion` is purely informational and does not affect Helm's behavior. The actual application version is determined by the container image tag or other values you define. Helm uses the chart `version` for release management.
Mistake
Helm release information is stored in ConfigMaps.
Correct
Helm v3 stores release metadata (including the rendered manifests and values) in Secrets in the same namespace as the release. Each release revision gets a new Secret. ConfigMaps are not used for this purpose.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
`helm install` creates a new release. If a release with that name already exists in the namespace, it fails. `helm upgrade` modifies an existing release. To handle both scenarios, use `helm upgrade --install`, which installs if the release doesn't exist, or upgrades if it does.
Use `helm get manifest <release-name> -n <namespace>`. This outputs the rendered YAML that was applied to the cluster. For the values used, use `helm get values <release-name>`.
Yes, Helm v3 works with Autopilot clusters. However, your chart must not require features not supported by Autopilot, such as privileged containers, host network access, or DaemonSets without tolerations. Always test with `helm template` and validate against Autopilot constraints.
Helm values are stored in plaintext in the release Secret. To avoid exposing secrets, use external secret management tools like Google Cloud Secret Manager or Sealed Secrets. You can reference secrets via environment variables or CSI drivers. Alternatively, use `--set` with a secure pipeline variable, but note that it will still be stored in the release Secret.
`Chart.lock` is generated by `helm dependency update`. It records the exact version and checksum of each dependency, ensuring reproducible builds. Commit this file to your version control system to lock dependency versions.
First, list revisions with `helm history <release-name> -n <namespace>`. Then run `helm rollback <release-name> <revision-number> -n <namespace>`. Helm will reapply the manifests from that revision. The rollback creates a new revision (incrementing the revision number).
`version` is the chart version, used by Helm for release management and dependency resolution. It must follow semantic versioning. `appVersion` is informational and indicates the version of the application packaged in the chart. It does not affect Helm's behavior.
You've just covered Helm Charts on GKE — now see how well it sticks with free ACE practice questions. Full explanations included, no account needed.
Done with this chapter?