Using Existing Helm Charts: Copy, Install, or Dependencies?

Using Existing Helm Charts: Copy, Install, or Dependencies?

I’ve been working with students on Kubernetes deployments recently, and I noticed something interesting: many patterns that have become second nature to me aren’t obvious to people just starting out. One of those patterns is how to properly use Helm dependencies instead of copying entire charts into your repository.

This post shares what I’ve learned about different approaches to using existing Helm charts and when each makes sense.

This post is for: Developers and DevOps practitioners who know the basics of Helm and want to understand the best way to customize and deploy existing Helm charts without creating maintenance nightmares.


TL;DR

Copying charts gives you full template control but creates maintenance burden. Updates require manual diffing. Use when the chart needs extensive modifications or doesn’t fit your needs.

Helm install with remote charts keeps your repository small but requires upstream to be online during deployment. Good for quick testing and simple deployments.

Helm dependencies (recommended starting point) make your customizations obvious through minimal values.yaml and turn upgrades into simple version bumps. Works best with well-designed charts.

Follow-up read: For deploying multiple charts together, see Managing Multi-Chart Kubernetes Deployments for patterns like umbrella charts, Helmfile, and GitOps tools.


The Problem: Deploying Argo Workflows

Let me show you a real example. A student wanted to deploy Argo Workflows to their Kubernetes cluster. They find the official Helm chart and face a question: how do I customize this for my needs?

Specifically, they need to:

  • Run the Argo Workflows UI under the /argo path
  • Use their private ingress controller
  • Configure specific ingress annotations for path rewriting

The chart exists. The question is: what’s the best way to use it?

Let’s explore three different approaches to solving this problem, starting with the most intuitive.


Copying the Entire Chart

The intuitive approach is to copy the chart into your repository and modify it directly.

Terminal window
# Download the chart
helm pull argo/argo-workflows --untar
# Copy it into your repo
cp -r argo-workflows my-deployments/charts/
# Modify values.yaml and templates as needed

You now have the complete chart in your repository. You can modify any file, any template, any value.

Benefits of Copying

Full template control: You can modify any template, any value, any resource. If the chart doesn’t quite fit your needs, you can reshape it however you want.

Complete independence: After copying, you own the chart. No network dependencies, no upstream changes breaking your deployments. You control everything.

Drawbacks of Copying

Understanding configuration becomes difficult: When you copy the entire chart, your values.yaml contains every possible configuration option. For Argo Workflows, that’s 800+ lines of YAML with dozens of top-level keys.

Six months later, when a colleague (or you) needs to understand what’s actually customized, they have to read through hundreds of lines trying to identify what was changed. There’s no clear signal showing which values matter for your specific deployment.

Updates become painful: Three months down the line, Argo Workflows releases a new version with bug fixes you need. Now you face a choice:

  • Manually diff your customized templates against the new chart version
  • Stay on the old version and miss the bug fixes

Both options are bad. The first requires significant manual work for every update. The second means falling behind on security patches.

When to Use Copying

Before dismissing copying entirely, there are legitimate scenarios where it’s the right choice:

The chart is poorly designed. Some charts expose only a handful of configuration options while hardcoding assumptions about your infrastructure. If you need to modify templates extensively just to make it work, copying (or finding a better chart) might be more practical than fighting the upstream design.

You’re creating an internal standard. Organizations often need to wrap third-party charts with additional resources, specific security policies, or company-wide defaults. Copying and maintaining an internal fork gives you complete control over the deployment standard.

The chart is abandoned or unstable. If the upstream repository is no longer maintained, or if new releases frequently introduce breaking changes, copying gives you stability. You control when (and if) to incorporate upstream changes.

You’re building a product on top of it. If you’re packaging the chart as part of a larger product with specific guarantees, copying and maintaining your own fork ensures you’re not dependent on upstream breaking your integration.

The key is being honest about maintenance costs. Copying means you own the updates, the security patches, and the bug fixes. If you’re prepared for that responsibility, copying can be the right pragmatic choice.


Helm Install with Remote Charts

Instead of copying, you can install directly from the upstream repository and provide your customizations via a values file.

Create a minimal values.yaml with only your customizations:

argo-workflows-values.yaml
server:
# Run under /argo on the private ingress
baseHref: /argo/
extraArgs:
- --base-href=/argo/
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/rewrite-target: '/$2'
ingressClassName: 'private-ingress'
paths:
- /argo(/|$)(.*)
pathType: ImplementationSpecific

Then deploy by referencing the remote chart and your values:

Terminal window
# Add the repository
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
# Install with specific version and your values
helm install my-argo argo/argo-workflows \
--version 0.45.0 \
-f argo-workflows-values.yaml

Benefits of Helm Install

Clarity: Your values.yaml shows exactly what you changed from defaults. Anyone reading it immediately sees your customizations without wading through hundreds of unmodified values. In the example above, it is clearly visible that we adjusted the ingress routing, serving the app on a certain path.

Easy upgrades: No template maintenance needed. Bump the version number in your install command and test. The upstream chart handles all the template complexity.

Drawbacks of Helm Install

Requires documentation: Your repository only contains the values file, so you need to document or script the installation command elsewhere.

Network dependency: Every deployment requires the upstream repository to be online. If it’s unavailable (network issues, repository moved), your deployment fails.

You can work around this by caching the chart locally first:

Terminal window
# Cache the chart locally
helm pull argo/argo-workflows --version 0.45.0
# Install from the cached .tgz file
helm install my-argo argo-workflows-0.45.0.tgz \
-f argo-workflows-values.yaml

This gives you offline deployment capability, though you need to manage the cached .tgz file yourself.

When to Use Helm Install

Use helm install for quick testing and exploration, when you want to try out a chart quickly without creating a full chart structure.


Helm dependencies let you declare which charts you depend on, cache them locally, and customize them through values, all without copying templates.

Create a minimal chart structure:

my-argo-workflows/
├── Chart.yaml
├── values.yaml
└── charts/ # Generated by helm dependency update

Declare the dependency in Chart.yaml:

Chart.yaml
apiVersion: v2
name: my-argo-workflows
version: 1.0.0
dependencies:
- name: argo-workflows
version: 0.45.0
repository: https://argoproj.github.io/argo-helm

Then create your customizations in values.yaml:

values.yaml
argo-workflows:
server:
# Run under /argo on the private ingress
baseHref: /argo/
extraArgs:
- --base-href=/argo/
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/rewrite-target: '/$2'
ingressClassName: 'private-ingress'
paths:
- /argo(/|$)(.*)
pathType: ImplementationSpecific

Note the top-level key argo-workflows: that matches the dependency name. All your customizations go under this key.

Run helm dependency update to fetch and cache the chart:

Download and pin dependencies
helm dependency update my-argo-workflows/

This downloads the chart and stores it in my-argo-workflows/charts/argo-workflows-0.45.0.tgz. This .tgz file is the complete chart, cached locally. The command also generates a Chart.lock file that pins the exact dependency versions for reproducible builds. Always commit this file to version control!

Chart.lock
dependencies:
- name: argo-workflows
repository: https://argoproj.github.io/argo-helm
version: 0.45.0
digest: sha256:abc123...
generated: '2025-11-22T10:15:30.123456789Z'

Note: You can commit the cached .tgz files to version control for fully offline deployments, or add charts/*.tgz to .gitignore and run helm dependency update during your deployment process.

Deploy your cart
helm install my-argo my-argo-workflows/

Benefits of Helm Dependencies

Same clarity as helm install: Your values.yaml shows exactly what you changed from defaults, just like the helm install approach. The difference is your chart structure makes everything self-contained.

Easy upgrades: Bump the version in Chart.yaml, run helm dependency update, and test. No manual diffing or merge conflicts.

Local caching: The .tgz file in your repository means you don’t need upstream available at deployment time, similar to how helm pull can cache for helm install.

Flexibility: You can still add custom resources. Create a templates/ folder and add your own manifests alongside the dependency:

my-argo-workflows/
├── Chart.yaml
├── values.yaml
├── charts/
│ └── argo-workflows-0.45.0.tgz # Cached dependency
└── templates/
├── custom-configMap.yaml # Your additions
└── custom-secret.yaml

Limitations of Helm Dependencies

Helm dependencies work best when the upstream chart is well-designed. If the chart doesn’t expose the configuration you need, you’re limited to the values it provides. You can’t modify the dependency’s templates directly (though you can add your own additional templates in your wrapper chart’s templates/ folder).

This isn’t a dependency problem though; it’s a chart design problem. If a chart requires major modifications to work for your use case, you have two options: find a better chart, or copy and maintain it yourself (see the copying section above).

When to Use Helm Dependencies

Default choice for well-designed charts: When the upstream chart exposes the configuration options you need and follows good chart design practices.

Team deployments with clear customizations: When you want your team to immediately understand what’s customized without reading hundreds of lines of default values.

Production deployments requiring reproducibility: When you need version control, easy upgrades, and the ability to track exactly which chart versions are deployed.


Which Approach Should You Choose?

AspectCopying ChartsHelm Install (Remote)Helm Dependencies
Clarity of customizationsHidden in thousands of linesClear in values fileClear in values file
Maintenance burdenHigh (you own all updates)Low (version bump)Low (version bump + dependency update)
Template customizationFull controlNoneNone (unless adding templates/)
Local cachingYes (full copy in repo)Optional (helm pull caching)Yes (cached .tgz in charts/)
Network dependencyNo (after copy)Optional (helm pull)No (after initial fetch)
Repository sizeLarge (all templates)Minimal (values only)Small (if .tgz committed)
Upgrade effortHigh (manual diff)Minimal (change version flag)Low (bump version, run update)
When to useExtensive mods or internal forksQuick tests, simple deploymentsDefault choice for well-designed charts

Handling Multiple Charts

This article covers using a single existing Helm chart. If you need to deploy multiple charts together (like an observability stack with Prometheus, Grafana, and Loki), see Managing Multi-Chart Kubernetes Deployments for patterns including:

  • Umbrella charts (bundling dependencies)
  • Custom deployment scripts
  • Helmfile
  • GitOps tools (ArgoCD/Flux)

Key Takeaways

Helm install with remote charts for exploration. Good for quick testing and experimenting with helm charts.

Beyond exploration, use Helm dependencies as your default. They provide clear customizations, easy upgrades, and work well with well-designed charts that expose good configurability. This should be your first approach for most scenarios.

Copy when the chart doesn’t fit. If you need extensive template modifications, the chart is poorly designed, or you’re maintaining an internal standard, copying is a pragmatic choice. Just be prepared to own the maintenance.

Your values.yaml is documentation. Keep it focused on what you actually changed from defaults. Anyone reading it should immediately understand your customizations and why they exist.

Evaluate chart quality before committing. A well-designed chart with good configurability works great with dependencies. A rigid chart with limited options might be better copied (or replaced entirely).


Resources:


I learned these patterns while managing two bare-metal Kubernetes clusters at the Professorship of Open Source Software. The goal of this article is to help you avoid common pitfalls and choose the right approach for your specific use case.