Using multiple sources for a Helm Chart deployment in ArgoCD
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-guestbook
directory on the argocd-example-apps
GitHub 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:
For our tests, we can accept the default values given by GitHub, but if needed, we can customize them:
The Repository should be forked by now and we can verify it by reading the “forked from” section:
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.
We should have our repository created correctly:
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:
We need to give the file a name, then paste the files contents and commit the changes:
We can use the default values for the commit details:
Now we have our values.yaml
repository ready for our 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:
If you click on the application name, you can get more details of the current state:
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:
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.
Then click on the edit button:
Change the replicaCount
value from 1 to another value, for example, 3 and then commit these changes to the main branch.
In 3 minutes, it should be synced, or less if you press the Sync button:
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:
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:
Change the service name to another value and commit the changes:
We should see the new name for the service deployed after 3 minutes in our ArgoCD WebUI:
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:
Conclusion
In this article, we have learned how to use the ArgoCD multiple-source application feature to inject avalues.yaml
file 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.