Purple white and red flowers.
Our garden is growing. We've raised a Series A funding round.
Read more here

ArgoCD, Helm Charts, and Garden: A winning GitOps combination for CI/CD

Prathisrihas Reddy Konduru
Prathisrihas Reddy Konduru
March 28, 2023

Continuous Integration and Continuous Deployment (CI/CD) have become an essential part of the workflow in modern software development. These practices allow developers to build, test, and deploy code changes frequently and with minimal human intervention.

GitOps is a methodology that extends the principles of CI/CD by using Git as the single source of truth for the desired state of the system, and then uses automation (agents that run as reconcilers) to ensure that the live system matches that desired state.

GitOps is a modern way to manage cloud-native systems that are powered by Kubernetes. It leverages a policy-as-code approach to define and manage every layer of the modern application stack - infrastructure, networking, application code, and the GitOps pipeline itself.
~ Weaveworks

The right GitOps tool will match the state of a running system with that of the desired state in version control systems (VCS). However, challenges arise when such tools have to be used in development workflows where certain tasks (like live code synchronizing, unit tests, integration tests, etc.) have to be performed even before code makes its way to the VCS.

In this article, we’ll take a look at how we can use ArgoCD (one such GitOps tool) for production and Garden for development. Together, these tools improve your team’s development and deployment happiness by creating a clear path from inner loop development to production.

Consistent, repeatable deployments with Garden and ArgoCD

What is Garden?

Garden is a powerful development tool that simplifies the process of building and testing containerized applications, allowing engineers to focus on their work with ease. Garden is not limited to local development, it also excels in Continuous Integration (CI) and Continuous Deployment (CD) workflows, helping teams streamline their testing and deployment processes.

Garden's flexibility and compatibility make it a great choice for a wide range of use cases. Whether deploying to production or staging environments, Garden can help you get there faster and with greater confidence. If you're already using other CD tools, Garden integrates seamlessly with them too.

Garden allows you to codify your stack with YAML declarations that describe how your system is built, deployed, and tested, and uses these definitions to provide a unified interface for deploying and managing services. This means it is well-suited for teams working on microservices or other distributed systems and supports remote development, especially on Kubernetes. 

How Garden and ArgoCD work together

By using Garden during the development and CI phases and ArgoCD to automate the deployment process, teams can easily manage and deploy their applications in a consistent and repeatable way. Working together, these tools keep developers in their inner loops.

Garden and ArgoCD work together to deploy applications

Using Helm to link ArgoCD and Garden

Backed by a strong, open-source community, Helm can help with templating and packaging of Kubernetes manifests that will in turn help with releasing and distributing them. Using helm charts also fits right into our workflow as argocd-image-updater can update image-related parameters of helm charts in <span class="p-color-bg">.argocd-source.yaml</span>. This will help ArgoCD to sync app-related changes to the production environment by using parameter overrides. A similar workflow can also be implemented by using Kustomize in place of Helm.

When paired with Helm, Garden can help package code with configuration metadata distributed across Kubernetes clusters. Garden also makes it easy to manage the deployment of applications on dev environments while keeping the option of re-using the Helm chart for deploying to different environments open.

With development workflows moving away from local workstations to remote Kubernetes clusters, tools like Garden used in combination with Helm charts add a ton of advantages. These tools enable engineers to focus on the things that matter the most while iterating continuously on code changes.

All together now: Helm, Garden, and ArgoCD

In order to demonstrate the combined functionality of Garden, ArgoCD, and Helm, let's take a look at a specific example project. This project showcases how developers can use Garden for their inner loop development, while simultaneously leveraging the declarative setup and continuous delivery capabilities of ArgoCD.

The project in question is a three-tier application comprised of a web layer, an API layer, and a PostgreSQL database. For the sake of simplicity, the source code and Helm manifests for the application are kept in the same repository. As previously discussed, Helm manifests are useful for keeping templates consistent across multiple environments, which in turn simplifies the process of deploying the application to different clusters.

At a high level, the workflow will look like the following:

  • Consider we have two k8s clusters, one of them being a Dev/CI cluster while the other is a production one. The purpose of the Dev/CI cluster is to have resources deployed via <span class="p-color-bg">garden</span> during the development/CI phases while the prod cluster gets deployments via ArgoCD. In this example, Dev/CI cluster has Garden’s In-Cluster building, in particular cluster-buildkit <span class="p-color-bg">buildMode</span>, enabled to build images.

<span class="p-color-bg"># project.garden.yaml</span>

kind: Project
name: vote-helm-argocd
defaultEnvironment: "${local.env.GITHUB_ACTIONS ? 'ci' : 'gke-gitops-dev'}"
    context: gke_garden # update with appriopriate context
    buildMode: cluster-buildkit
      - name: regcred
        namespace: default
      hostname: index.docker.io
      namespace: srihasg # Update with your user's registry namespace
  dev-k8s-namespace: ${project.name}-${local.username}
  ci-k8s-namespace: ${project.name}-${local.username}-${local.env.GITHUB_REF_NAME || "branch"}-${local.env.GITHUB_RUN_NUMBER || 0}
  - name: local
      baseHostname: vote.local.app.garden
  - name: gke-gitops-dev
    defaultNamespace: ${var.dev-k8s-namespace}
      baseHostname: ${var.dev-k8s-namespace}.dev-1.sys.garden
  - name: ci
    defaultNamespace: ${var.ci-k8s-namespace}
      baseHostname: ${var.ci-k8s-namespace}.ci.sys.garden
  - name: local-kubernetes
    environments: [local]
    context: docker-desktop
  - name: kubernetes
    environments: [gke-gitops-dev, ci]
    $merge: ${var.common-k8s-provider-config}
    namespace: ${environment.namespace}
    defaultHostname: ${var.baseHostname}
  • Developer uses Garden to develop in a production-like development environment. Once ready, they push their code to their VCS provider (e.g. GitHub or GitLab) on a feature branch. This triggers a CI pipeline where Garden is also used to run tests and create preview environments.
  • When the code is approved and merged to the main branch, another CI job is triggered where Garden is used to publish images via <span class="p-color-bg">garden publish</span>
  • Once the container image has been published, ArgoCD Image updater picks the image, based on the <span class="p-color-bg">update-strategy</span> annotation in the ArgoCD application and updates the helm parameters in the <span class="p-color-bg">.argocd-source-api.yaml</span>

<span class="p-color-bg"># argocd-applications/api.yaml</span>

apiVersion: argoproj.io/v1alpha1
kind: Application
  name: api
  namespace: argocd
    argocd-image-updater.argoproj.io/image-list: api=gardendev/api-image
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/git-branch: main
    argocd-image-updater.argoproj.io/api.update-strategy: name
    argocd-image-updater.argoproj.io/api.allow-tags: regexp:^main-[0-9]+$
    argocd-image-updater.argoproj.io/api.helm.image-name: image.repository
    argocd-image-updater.argoproj.io/api.helm.image-tag: image.tag
    automated: {}
    - CreateNamespace=true
    namespace: vote-helm-default
    server: https://kubernetes.default.svc
  project: default
    targetRevision: HEAD
    path: api
      - values-prod.yaml

<span class="p-color-bg"># api/chart/.argocd-source-api.yaml</span>

  - name: image.repository
    value: gardendev/api-image
    forcestring: true
  - name: image.tag
    value: main-27
    forcestring: true

<aside>💡 ArgoCD Image updater uses the same repo credential as ArgoCD. For our example, we use a GitHub App to commit changes back to the GitHub repo.


  • ArgoCD watches for updates to the GitHub repo, and once the image tag has been updated, it sync’s the app via App of apps pattern.

Detailed setup instructions have been put up on our example’s README. We are always open to collaborate and make it better.

A GitOps setup for success

Imagine an organization that has a GitOps setup to manage deployments across different environments. Engineers may be stuck with long wait times as changes are built, tested, and then packaged as Helm charts before they can be deployed and previewed.

This is a clear indication that it is time to move development to remote Kubernetes clusters, leveraging benefits of tools like Garden.

Garden can absolutely make the engineer’s day better by hot reloading changes, caching tests and natively templating variables in Helm values files, and many more added benefits out of the box.

Careful selection of the appropriate tools for both Continuous Integration (CI) and Continuous Delivery (CD) workflows can have a significant positive impact on engineering efficiency. Not only can it reduce wait times for engineers, but it can also increase the frequency and reliability of changes deployed to production.

If you'd like to learn more about Garden, check out our Quickstart guide or rubber duck with us on Discord.

previous arrow
newt arrow