SKIP TO CONTENT

External Value Files in Argo CD With ApplicationSets

Oreon Lothamer
May 10, 2022
5 min read
We’ve been using Argo CD to deploy to our Kubernetes clusters for a while now.

The overall experience has been great, but as we get more advanced we have started to wish for additional options. One issue we’ve had is the value files for helm charts have to exist in the same repo as the helm chart.

This is fine when we are deploying a standalone helm chart we control, but it is not so easy when using existing helm charts or our own helm charts that are meant to be deployed to all clusters we spin up. So we end up supplying values as overrides on the Application manifest. There are some concerns with this approach, like wanting to separate permissions to update Applications from permissions to update the values used.

There are a few different ways people have gone about addressing this. Some use proxy charts that just consist of value files and a dependency on the regular chart. Some have created plugins for Argo CD that handle pulling in separate value files. And there is also a proposal being worked on to implement a feature in Argo CD to support external value files. While we were enabling our platform to support Argo CD managing multiple clusters we realized we could use the same ApplicationSets we were using to deploy to all clusters to also grab helm values from separate repos.

ApplicationSets have multiple different generators you can use to generate the Applications to be deployed. The Git Generator: Files is what gives us the ability to pass values from a separate repo. It will look in a git repo for files that define the clusters and we can include overrides there. It effectively does what we were already doing with the values as overrides, but allows us to store those values in a separate repo. Here is an example:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: example
spec:
  generators:
  - git:
      repoURL: https://github.com/example.git
      revision: HEAD
      files:
      - path: "examples/**.yaml"
  template:
    metadata:
      name: '{{name}}-example'
    spec:
      project: default
      source:
        helm:
          valueFiles:
          - values.yaml
          values: |-
            {{values}}
        repoURL: https://github.com/bitnami/charts.git
        targetRevision: HEAD
        path: "bitnami/nginx"
      destination:
        server: '{{address}}'
        namespace: default  

In the example repo you would have a yaml file (ie in-cluster.yaml) that defines your cluster and the overrides:

name: "in-cluster"
address: "https://kubernetes.default.svc"
values: |
  replicaCount: 2
  resources:
    limits:
      cpu: 100m
      memory: 128Mi 

This will generate an Application with the values specified and targeting the cluster specified in the in-cluster.yaml file.

If we are just using this to pass values to the cluster Argo CD is running on, and don’t need to provide the ability to deploy to other clusters, we can simplify:

values: |
  replicaCount: 2
  resources:
    limits:
      cpu: 100m
      memory: 128Mi 

And then we don’t need to include the name or address in the in-cluster.yaml file. That way the files will only contain the values we are trying to override and we can separate roles and responsibilities.

values: |
  replicaCount: 2
  resources:
    limits:
      cpu: 100m
      memory: 128Mi 

Sign up for our newsletter to join our impact-driven mission.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.