Cluster Specific Template Overrides in ArgoCD ApplicationSets Using Cluster Generators
Tags: ops, argocd, kubernetes, tutorial
Published: 2022-08-10 08:36:00

---
title: Cluster Specific Template Overrides in ArgoCD ApplicationSets Using Cluster Generators
published: true
description: A note on how to do template overrides in ArgoCD ApplicationSets using cluster generators.
tags: #ops #argocd #kubernetes #tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hrd4iy62xccu6au4goa.png
# Use a ratio of 100:42 for best results.
---

## Introduction

Creating `ApplicationSets` is a great tool dry up application templates in ArgoCD. You can generate similar applications where the only difference is the namespace for `staging` and `production`, or the labeling for tracks like `canary` and `stable`. So consider this use-case:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: example-application
  namespace: argocd
spec:
  syncPolicy:
    preserveResourcesOnDeletion: true
  generators:
    - clusters:
        selector:
          matchLabels: #...
        values:
          env: staging
          track: stable
    - clusters:
        selector:
          matchLabels: #...
        values:
          env: production
          track: stable
    - clusters:
        selector:
          matchLabels: #...
        values:
          env: production
          track: canary
template:
  #...
```

These values are easy to set as they are mere strings. You can use simple interpolation to use these. In our case, we use several different values files based on these values in the template specs.

```yaml
valueFiles:
  - values.yaml
  - 'values.{{values.env}}.yaml'
  - 'values.{{values.track}}.yaml'
  - 'secrets.{{values.env}}.yaml'
```

## The Problem

This is all fine and dandy until you need something more complex. Imagine the case where you would like to set only one of these clusters to do automatic syncing. In our case, whenever we change the version in the helm chart, we'd like staging to be synced right away. We can set the `syncPolicy`, but its interface is an object, and you cannot interpolate that in a cluster specific way. To enable this we need to use the following:

```yaml
syncPolicy:
  automated: {}
```

Where do you set these overrides if you want it to be merged only for staging for example?

## The Solution

You can set template overrides in the `cluster` object. This will be merged with the template defined in this chart.

```yaml
- clusters:
    selector:
      matchLabels: #...
    values:
      env: staging
      track: stable
    template:
      spec:
        syncPolicy:
          automated: {}
```

But one does not simply set template override, for some reason there are mandatory keys to be set, even if they are just placeholders. This means there is a minimal shape that you need to set to set anything for the cluster in hand. That looks like this:

```diff
  template:
+   metadata: {}
    spec:
+     project: app
+     destination: {}
+     source:
+       repoURL: http://github.com/example/helm-charts
      syncPolicy:
        automated: {}
```

So the staging cluster should look like this to be valid:

```yaml
- clusters:
    selector:
      matchLabels: #...
    values:
      env: staging
      track: stable
    template:
      metadata: {}
      spec:
        project: web
        destination: {}
        source:
          repoURL: http://github.com/example/helm-charts
        syncPolicy:
          automated: {}
```

So there you go, if you're using cluster generators and would like a cluster specific override of the sync policy, now you know how to do that.