Helm with ArgoCD

A comprehensive guide to Helm with ArgoCD covering GitOps, ArgoCD integration, automated sync, and best practices for managing Helm releases with GitOps.

GitOps ArgoCD Integration Automated Sync
What is GitOps?

GitOps is a paradigm for managing Kubernetes and infrastructure using Git as the single source of truth. In GitOps, Git repositories contain the entire desired state of the system, including Helm chart configurations. An operator (like ArgoCD) continuously reconciles the actual cluster state with the desired state stored in Git.

GitOps brings several benefits:

  • Improved Auditability: All changes are tracked in Git
  • Faster Recovery: Rollback is just reverting a commit
  • Simplified Operations: Everything is declarative
  • Consistency: Same process for all environments
  • Security: No direct cluster access needed
Key Concept: In GitOps, you never run helm install manually. Instead, you commit Helm chart configurations to Git, and ArgoCD automatically syncs them to your cluster.
ArgoCD Architecture

ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. It follows a pull-based model where the controller continuously monitors Git repositories and synchronizes cluster state.

ArgoCD API Server

Control plane component
Exposes the ArgoCD API and UI. Handles authentication, authorization, and manages application state.

Application Controller

Reconciliation engine
Continuously watches Git repositories and cluster state. Detects drifts and initiates synchronization.

Redis Cache

Caching layer
Caches Git repository state and manifests to improve performance.

Repo Server

Repository management
Clones Git repositories and generates manifests using Helm, Kustomize, or plain YAML.
# Install ArgoCD kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml # Install ArgoCD CLI curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 chmod +x argocd sudo mv argocd /usr/local/bin/ # Access ArgoCD UI kubectl port-forward svc/argocd-server -n argocd 8080:443 # Get initial admin password kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d # Login via CLI argocd login localhost:8080 --username admin --password --insecure # Change password argocd account update-password
Helm Integration with ArgoCD

ArgoCD supports Helm charts natively. You can use Helm charts as sources for ArgoCD applications, and ArgoCD will render and deploy them.

# ArgoCD Application with Helm chart apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app namespace: argocd spec: project: default source: repoURL: https://github.com/myorg/helm-charts targetRevision: HEAD path: charts/my-app helm: # Helm values files valueFiles: - values.yaml - values-production.yaml # Helm parameters parameters: - name: replicaCount value: "5" - name: image.tag value: "v1.2.3" # Release name releaseName: my-release # Helm version version: v3 destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true # ArgoCD Application with Helm repository apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: nginx namespace: argocd spec: project: default source: repoURL: https://charts.bitnami.com/bitnami chart: nginx targetRevision: 15.0.0 helm: values: | replicaCount: 3 service: type: ClusterIP destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true
Helm + ArgoCD Benefits:
  • Use Helm charts from Git or Helm repositories
  • Override values with Helm parameters
  • Automatic sync with Git changes
  • Rollback to any Git commit
  • Multi-environment deployments
  • Web UI for visualization
ApplicationSets: Multi-Environment Deployments

ApplicationSets are a powerful feature that generates ArgoCD Applications using templates and generators. They enable dynamic, scalable management of Helm charts across clusters and environments.

# ApplicationSet for Helm charts apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: helm-apps namespace: argocd spec: generators: - clusters: selector: matchLabels: environment: production template: metadata: name: '{{name}}-my-app' spec: project: default source: repoURL: https://github.com/myorg/helm-charts targetRevision: HEAD path: charts/my-app helm: valueFiles: - values-{{metadata.labels.environment}}.yaml parameters: - name: cluster.name value: '{{name}}' - name: environment value: '{{metadata.labels.environment}}' destination: server: '{{server}}' namespace: production syncPolicy: automated: prune: true selfHeal: true # Git Generator for directory-based ApplicationSets apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: directory-apps namespace: argocd spec: generators: - git: repoURL: https://github.com/myorg/helm-charts revision: HEAD directories: - path: charts/* template: metadata: name: '{{path.basename}}' spec: project: default source: repoURL: https://github.com/myorg/helm-charts targetRevision: HEAD path: '{{path}}' helm: valueFiles: - values.yaml destination: server: https://kubernetes.default.svc namespace: default # List Generator for specific environments apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: env-apps namespace: argocd spec: generators: - list: elements: - env: dev namespace: dev replicas: "1" - env: staging namespace: staging replicas: "2" - env: prod namespace: production replicas: "5" template: metadata: name: 'my-app-{{env}}' spec: project: default source: repoURL: https://github.com/myorg/helm-charts targetRevision: HEAD path: charts/my-app helm: parameters: - name: replicaCount value: '{{replicas}}' - name: environment value: '{{env}}' destination: server: https://kubernetes.default.svc namespace: '{{namespace}}'
ApplicationSet Benefits:
  • Manage many applications with one resource
  • Dynamic generation based on clusters or Git
  • Consistent configuration across environments
  • Easy to scale to hundreds of applications
  • GitOps-friendly with declarative configuration
Automated Sync and Self-Healing
# Sync Policy options syncPolicy: # Automated sync automated: prune: true # Delete resources not in Git selfHeal: true # Correct drift automatically allowEmpty: false # Don't allow empty applications # Sync options syncOptions: - CreateNamespace=true - PruneLast=true - ApplyOutOfSyncOnly=true - Validate=true - PrunePropagationPolicy=foreground # Retry policy retry: limit: 5 backoff: duration: 5s factor: 2 maxDuration: 3m # Manual sync (no automated) apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app spec: syncPolicy: syncOptions: - CreateNamespace=true # Sync Waves for ordered deployment apiVersion: v1 kind: ConfigMap metadata: name: config annotations: argocd.argoproj.io/sync-wave: "1" # Deploy first --- apiVersion: apps/v1 kind: Deployment metadata: name: app annotations: argocd.argoproj.io/sync-wave: "5" # Deploy later --- apiVersion: v1 kind: Service metadata: name: app annotations: argocd.argoproj.io/sync-wave: "3" # Deploy after config, before deployment # Sync Hooks for pre/post sync actions apiVersion: batch/v1 kind: Job metadata: name: pre-sync-job annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/hook-delete-policy: HookSucceeded spec: template: spec: containers: - name: migration image: myapp:migration command: ["python", "migrate.py"] restartPolicy: Never # Post-sync hook apiVersion: batch/v1 kind: Job metadata: name: post-sync-job annotations: argocd.argoproj.io/hook: PostSync argocd.argoproj.io/hook-delete-policy: HookSucceeded spec: template: spec: containers: - name: test image: myapp:test command: ["python", "smoke-test.py"] restartPolicy: Never
Automated Sync Best Practices:
  • Use prune: true to remove orphaned resources
  • Use selfHeal: true to correct drift
  • Use sync waves for ordered deployment
  • Use hooks for pre/post sync actions
  • Set appropriate retry policies
  • Test sync policies in staging first
Helm Secrets with ArgoCD
# Using Sealed Secrets with ArgoCD # 1. Create SealedSecret in chart # templates/sealed-secret.yaml apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: name: {{ include "my-app.fullname" . }}-secrets spec: encryptedData: password: {{ .Values.secrets.password }} template: metadata: name: {{ include "my-app.fullname" . }}-secrets # 2. Add sealed secrets to values # values.yaml secrets: password: AgBy... # Encrypted with kubeseal # 3. ArgoCD Application apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app spec: source: repoURL: https://github.com/myorg/helm-charts path: charts/my-app helm: valueFiles: - values.yaml - secrets.yaml # Contains sealed secrets destination: server: https://kubernetes.default.svc namespace: default # Using helm-secrets plugin with ArgoCD # ArgoCD supports helm-secrets via config management plugin apiVersion: v1 kind: ConfigMap metadata: name: argocd-cm namespace: argocd data: configManagementPlugins: | - name: helm-secrets generate: command: ["sh", "-c"] args: ["helm secrets template $ARGOCD_APP_NAME . -f secrets.yaml"] # Using External Secrets Operator with ArgoCD # templates/external-secret.yaml apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: {{ include "my-app.fullname" . }}-secrets spec: secretStoreRef: name: vault-store kind: SecretStore target: name: {{ include "my-app.fullname" . }}-secrets data: - secretKey: password remoteRef: key: app/db property: password
Secrets with GitOps:
  • Never store plaintext secrets in Git
  • Use Sealed Secrets for GitOps-safe encryption
  • Use External Secrets Operator for dynamic secrets
  • Use helm-secrets plugin for encrypted values
  • Configure ArgoCD to decrypt secrets during sync
Helm with ArgoCD vs Traditional Helm
Feature Traditional Helm Helm with ArgoCD
Deployment Method Manual helm install/upgrade Automated sync from Git
Source of Truth Local values files Git repository
Audit Trail Limited (shell history) Complete (Git history)
Rollback helm rollback Git revert
Multi-Cluster Manual per cluster ApplicationSets
Drift Detection Manual Automatic
Self-Healing No Yes (with selfHeal)
UI No Yes (ArgoCD UI)
Complexity Low Medium
Frequently Asked Questions
What is the difference between Helm and ArgoCD?
Helm is a package manager for Kubernetes that creates and manages releases. ArgoCD is a GitOps continuous delivery tool that syncs Git repositories to Kubernetes clusters. ArgoCD can use Helm charts as sources.
Can ArgoCD deploy Helm charts?
Yes! ArgoCD supports Helm charts natively. You can use Helm charts from Git repositories or Helm repositories as sources for ArgoCD applications.
How do I override Helm values in ArgoCD?
Use the helm.valueFiles field to specify values files, or use helm.parameters to set individual values. You can also use helm.values for inline values.
What is an ApplicationSet?
An ApplicationSet is a resource that generates one or more ArgoCD Applications using a template and generators. It enables dynamic, scalable management of Helm charts across clusters and environments.
How do I handle secrets with ArgoCD and Helm?
Use Sealed Secrets (encrypt secrets in Git), helm-secrets plugin (encrypted values), or External Secrets Operator (sync from external providers). Never store plaintext secrets in Git.
What is the difference between automated and manual sync?
Automated sync automatically applies changes from Git to the cluster. Manual sync requires user intervention to apply changes. Use automated for production with proper safeguards.
How do I rollback with ArgoCD?
Rollback is a simple Git revert. ArgoCD automatically syncs the revert to the cluster. You can also use the ArgoCD UI to rollback to a previous revision.
What are sync waves in ArgoCD?
Sync waves control the order of resource deployment. Resources with lower wave numbers deploy first. Use argocd.argoproj.io/sync-wave annotation to specify the wave.
Previous: Chart Provenance Next: Helm with GitHub Actions

GitOps with ArgoCD transforms Helm deployments by making Git the source of truth. Embrace declarative deployments, automated sync, and auditability for modern, reliable infrastructure management.