Personally I find ArgoCD works perfectly fine for kustomize and helm charts. Each tool is used in the following manner:
argoCDfor configuring kubernetes deployments, keeping Applications in sync with the state of the git repo (GitOps)helmcharts we use it to install typical third party charts such asargoCD,external-secrets,cert-manager,istiod,kyverno, etc.kustomizeis great a customizing the different values in k8s config files between different environments.
Here is the Github repo with example that you can use to structure your project or at least as a reference.
From now own we will consider {env} as dev or prod . you can call your environments whatever you want but those two are typical bare minimum environments in multiple companies.
Here is a top level of how I currently organize my projects:
```
├─ infra # Infrastructure as Code
└─ kubernetes # Code for configuring GKE and custom k8s resources
├─ kustomize
| ├─ ApplicationSet.{env}.yaml # The base AppSet per environment
| ├─ base # base k8s resources for all environments
| └─ overlays # kustomize overlays for customizing different environments
|
└─ helm
├─ charts # Helm charts downloaded by using `helm pull {REPO}/{NAME} --untar`
└─ values # values for customizing helm charts per environment
```
helm subdirectory
Lets start with the helm/ subdirectory at available here. This subdir just contains dummy files. The important thing to notice here is that helm/charts/ is where you download and untar the charts from third parties such as the argocd helm chart, or the cert-manager helm chart. From this chart you will copy and paste the values.yaml file into helm/values/{chart}/{env}.values.yaml, where env will equal to a short prefix of your environment.
Including the helm charts in your repo has the following advantages:
- Allows you to easily compare your custom
helm/values/{chart}/{env}.values.yamlfile with the original untouchedvalues.yamlfile athelm/charts/{chart}. This is extremely useful when you want to see what was changed for your environment. - Allows you to install directly from your own repo, which gives you more consistent builds, since you can't warranty third party repos to be available, to remain in same domain or to respect semantic versioning.
- Allows developers to check easily and fast what resources will be installed by the helm chart at path
helm/charts/{chart}
The main disadvantage is:
- Every time you add a new chart it increases the Pull Request size making it harder to code review.
In my opinion the advantages here clearly outweighs the disadvantages.
kustomize subdirectory
Now lets proceed with subdir kustomize available here.
At the top level you will notice we have our ArgoCD ApplicationSet one per environment at path: kustomize/ApplicationSet.{env}.yaml
Each of these ApplicationSet will configure two ArgoCD "App of Apps":
- helm-apps: App of Apps for all helm charts
- custom-apps: App of Apps for all non helm charts, basically everything that is your custom code.
# kustomize/ApplicationSet.dev.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: appset-dev
namespace: argocd
spec:
goTemplate: true # activate Go templating
generators:
- list:
elements:
# App of apps for all helm charts
- appName: helm-apps
appType: "helm"
path: kubernetes/kustomize/overlays/dev/helm-apps
syncWave: 0
# App of apps for all non helm charts
- appName: custom-apps
appType: "custom"
path: kubernetes/kustomize/overlays/dev/custom-apps
syncWave: 1
template:
# Application Metadata
metadata:
name: "{{.appName}}"
namespace: argocd
finalizers:
# needed so k8s resources are deleted when app is deleted as well
- resources-finalizer.argocd.argoproj.io
labels:
appType: "{{.appType}}"
annotations:
# order of deployment based on syncWave
argocd.argoproj.io/sync-wave: "{{.syncWave}}"
spec:
# spec same as it (spec field) would be in a
# typical ArgoCD Application.yaml, just replace
# generator values defined above.
project: default
source:
repoURL: git@github.com:my-org/my-example-repo.git
targetRevision: dev
path: "{{.path}}" # path must point to kustomize overlays
destination:
server: 'https://kubernetes.default.svc'
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: true
syncOptions:
- PruneLast=true
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 2
Lets continue diving into kustomize sub directory it has two sub directories:
└─ kustomize
├─ base # base k8s resources for all environments
└─ overlays # kustomize overlays for customizing different Both kustomize/base and kustomize/overlays have helm-apps sub directory and a custom-apps sub directory.
helm-appscontains the argoCDApplicationconfiguration pointing tohelm/charts/{chart}and thehelm/values/{env}.values.yaml. Check base kustomization file for ArgoCDkustomize/base/helm-apps/argocd-app.yamland overlay fordevenvironment atkustomize/overlays/dev/helm-apps/argocd-app.yamlfor reference of how this works.custom-appscontains a simplebusyboxhttp server I have added for your reference make sure to check respectivebaseandoverlaydirectories to understand how to structure custom resources.
Once you have everything in place you can scale this dir structure which works well for multiple of applications in same cluster. You might want to refactor and break down custom-apps into smaller chunks once you reach a significant number of apps.