Using multiple sources for a Helm Chart deployment in ArgoCD

David Hernandez Valencia
Globant
Published in
10 min readDec 13, 2023
Image generated with Bing Image Creator

As a DevOps engineer who uses ArgoCD for k8s deployments, I have found myself looking for ways to cleanly separate the Git repository that holds the values.yaml file responsible for holding the values to use for a Helm Chart deployment from the chart itself, even if the chart is stored on a Git or Helm. This configuration helps keep the git commit history clean in the Helm Chart Git repository when only changes to thevalues.yaml are necessary for a cleaner git commit log while also keeping track of the changes of the values.yaml file itself.

In my research for options that provide easy maintenance for this dual source setup when using a single application in ArgoCD, I have found a beta feature (at the time of the writing of this article) that has helped solve this issue. This feature it’s on its way to being supported for both the ArgoCD UI and CLI (ArgoCD multiple sources documentation).

As it has helped me in my daily work, I want to share how to use this feature that the ArgoCD project contributors have developed. This article will focus on how to set up the multiple source feature for an application managed by ArgoCD by using an example Helm Chart provided by the ArgoCD project. We will copy it into our GitHub repo for testing purposes and a values.yaml file provided by ourselves in a different GitHub repo.

Prerequisites

Here’s a list of the tools you will need to implement this example code of a multi-source application on ArgoCD:

  • A working Kubernetes cluster for testing purposes on a cloud provider or on your local computer. If you don’t have a Kubernetes test environment (cloud or local) available and want to install it on your local computer, I recommend using Rancher Desktop as it has an easy install procedure and maintenance (Rancher Desktop installation guide). It can be installed on Windows, Linux and MacOS. Other projects like K3s, Kind, and Docker Desktop can be used.
  • kubctl cli installed (kubernetes.io instructions or homebrew instructions).
  • ArgoCD installed on the Kubernetes cluster (ArgoCD getting started article) and optionally, the ArgoCD UI can be enabled if you want to see the deployment status in a GUI, as we will do in this article.
  • A GitHub account (instructions). Any Git repository can work, but we will be using GitHub in this article’s instructions.

Enabling the Helm Chart code repo on GitHub

We will be enabling our own repo based on the ArgoCD project Helm chart example found in the helm-guestbookdirectory on the argocd-example-appsGitHub repository.

We will be forking this project so we will be able later to modify the chart contents and test if ArgoCD is able to catch up with the latest changes on the Helm chart code automatically.

For this visit the argocd-example-apps GitHub repo and fork the project in your GitHub account, in my example, I’ll be using the same name for my own fork.

Click on the fork options and then on the “Create new fork” button:

argocd-example-apps public GitHub repo

For our tests, we can accept the default values given by GitHub, but if needed, we can customize them:

Creation of a fork repo from the public argocd-example-apps repo

The Repository should be forked by now and we can verify it by reading the “forked from” section:

argocd-example-apps fork repo created

Enabling the values.yaml repo on GitHub

We will create a repository from scratch on our GitHub account for the repository that will hold the values.yaml file.

For this, we can visit the following link: https://github.com/new.

Here are the values I used to create this repo, I’ve created it as a public repo just to make it much easier to use on my ArgoCD local test environment, but in case you want to use a private repo be sure to add the credentials to the repo as described in this article.

Creation of the helm-values repo

We should have our repository created correctly:

Values repo created

Now, we need to populate this repository with a working values.yaml file, for this, we can create a new commit from the GitHub web UI and add the contents of the following file (taken from the values.yaml file in the ArgoCD example repo).

# Default values for helm-guestbook.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
repository: gcr.io/heptio-images/ks-guestbook-demo
tag: 0.1
pullPolicy: IfNotPresent

service:
type: ClusterIP
port: 80

ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
path: /
hosts:
- chart-example.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

Let’s add a new values.yaml file:

Create a new file in the values repo

We need to give the file a name, then paste the files contents and commit the changes:

Save contents of the new file in the values repo

We can use the default values for the commit details:

Commit message for the newly created file in the values repo

Now we have our values.yamlrepository ready for our tests:

Values repo ready for tests

Deploying the multiple sources application on ArgoCD

With the help of kubectl we will deploy our new application with multiple sources. We need to create a YAML file with the application specifications. You can use any editor and save it on your local machine, for example:

nano /tmp/helm-guestbook-multisource.yaml

Then add the following content to the file (remember to change both repoURL values to the ones you created in previous steps):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: helm-guestbook-multisource
namespace: argocd
spec:
project: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
destination:
server: https://kubernetes.default.svc
namespace: helm-guestbook-multisource
sources:
- repoURL: https://github.com/davidhv3/argocd-example-apps
path: helm-guestbook
targetRevision: HEAD
helm:
valueFiles:
- $values/dev-values.yaml
- repoURL: 'https://github.com/davidhv3/helm-guestbook-values-repo'
targetRevision: HEAD
ref: values

Now we proceed to apply the YAML file into the Kubernetes cluster:

kubectl apply -f /tmp/helm-guestbook-multisource.yaml

Note that we are creating the application with kubectl and not the WebUI, as the support for WebUI interactions is currently being worked on by the ArgoCD project contributors.

In the ArgoCD Web UI, we can verify the current state of the application:

Applications deployed by ArgoCD on the WebUI

If you click on the application name, you can get more details of the current state:

Status of the newly deployed application

We can also check the state of the resources by listing them on the newly created namespace for the application:

kubectl get all -n helm-guestbook-multisource

The output should be similar to this one:

NAME                                              READY   STATUS    RESTARTS   AGE
pod/helm-guestbook-multisource-75854bd79c-ldkq2 1/1 Running 0 8s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/helm-guestbook-multisource ClusterIP 10.43.36.234 <none> 80/TCP 10s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/helm-guestbook-multisource 1/1 1 1 9s

NAME DESIRED CURRENT READY AGE
replicaset.apps/helm-guestbook-multisource-75854bd79c 1 1 1 9s

Checking the multiple sources refresh capabilities

We will now test that the application gets updated if there is a change in the chart or values.yaml Git repositories. For any change in any of those, the application should be updated in the Kubernetes cluster automatically.

Note that by default, ArgoCD looks for updates in the Git repositories every 3 minutes, but you can manually click the sync button on the web UI if you want to see the changes applied earlier.

Validating changes in the values.yaml repository

At this moment, the application is configured only to use 1 pod, we will be updating the replica count in the dev-values.yaml file to confirm that ArgoCD is actively looking for changes in the values.yaml repo.

In the Web UI, we can see only one replica working at the moment:

Current status of the deployed application

Now we change the replicaCount value in our values.yaml repo, in my case, it would be on the helm-guestbook-values-repo.

We can do this on the GitHub website by following these steps:

In the repository source view, click the dev-values.yaml file.

Files in the values repo

Then click on the edit button:

Edit option of a file in the values repo

Change the replicaCount value from 1 to another value, for example, 3 and then commit these changes to the main branch.

Changes in the dev-values.yaml file in the values repo
Commit message in the values repo

In 3 minutes, it should be synced, or less if you press the Sync button:

Updated status of the deploy application in the ArgoCD WebUI

Validating changes in the Helm Chart repository

In order to test automatic sync is working also on the Helm Chart repository, we will make a change to one manifest of the Chart and see if the changes are deployed automatically into the Kubernetes cluster. In this example, we will be changing the name of the deployed service resource manually on the Helm Chart Git repository.

Before changing the name of the service, at this moment, it holds this value: helm-guestbook-multisource, based on the variable provided in the Chart definition:

Current name of the Kubernetes service

Similar to the previous edit we did for the replicasCount, we need to navigate to the service.yaml file of our fork of the argocd-example-apps repository and edit and commit the changes in the file to the master branch:

Edit option for the service.yaml file in the forked example repo

Change the service name to another value and commit the changes:

Changes for the service.yaml file in the forked example repo

We should see the new name for the service deployed after 3 minutes in our ArgoCD WebUI:

New name of the Kubernetes service

At this moment, we have verified that the application is monitoring both Git repositories correctly.

Other uses of the multiple sources feature

In this article, we have explored the use of multiple source applications to inject a values.yaml file into an application that uses a Helm Chart without having to modify the Helm Chart repository.

Another use of this feature is the possibility of merging multiple manifests files from multiple sources into one application, for example, in the multiple source feature explanation from the ArgoCD project, a Helm chart from a Chart registry and a Helm Chart from a Git repository are merged into one single application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
destination:
server: https://kubernetes.default.svc
namespace: default
sources:
- chart: elasticsearch
repoURL: https://helm.elastic.co
targetRevision: 8.5.1
- repoURL: https://github.com/argoproj/argocd-example-apps.git
path: guestbook
targetRevision: HEAD

Current limitations of the beta feature

There are some limitations known as this multiple source feature is still in a beta state. Some of the limitations are:

  • Web UI does not have the rollback option enabled. (As an alternative, you can use something at the Git repository level like a git revert command). This feature is being worked on on this pull request.
  • At the moment, you can’t create a multiple-source application from the Web UI. As an alternative, you can use the steps described in this article.

From the official documentation of the feature we also have a notification indicating that the syntax for the YAML file may change while it gets to a more stable release:

Beta feature warning on the multiple source feature documentation

Conclusion

In this article, we have learned how to use the ArgoCD multiple-source application feature to inject avalues.yamlfile from one repository to an application deployed from another while validating changes from both kubectl and the ArgoCD WebUI.

We also have learned of other uses for this feature and its current limitations as it is in a beta state, how to fork a repo in GitHub, and change repository files with the GitHub WebUI.

--

--