ArgoCD GitOps repository. Contains all application and platform definitions deployed to Kubernetes clusters.
The companion infrastructure repository (Terraform + Minikube) bootstraps ArgoCD and points it here.
ArgoCD manages itself entirely through this repo via an App-of-Apps pattern:
[Terraform] ββbootstrapsββ> bootstrap (ArgoCD Application)
β
βββwatchesββ> clusters/local/
β
βββββββββββ΄βββββββββββ
βΌ βΌ
platform demo (+ future apps)
β
platform/local/
(ingress-nginx, ...)
- Terraform creates a single seed Application called
bootstrap bootstrapreadsbootstrap/local.yamland creates thelocalApplicationlocalreadsclusters/local/and creates one Application per file found there- Each Application then manages its own resources on the cluster
gitops/
β
βββ bootstrap/
β βββ local.yaml # "local" ArgoCD Application (watches clusters/local/)
β
βββ clusters/
β βββ local/ # One directory per cluster environment
β βββ demo.yml # Deploys the demo Helm chart (values-local.yaml)
β βββ platform.yml # Deploys platform tools (points to platform/local/)
β
βββ platform/
β βββ local/ # Platform tools for the local cluster
β βββ ingress-nginx.yml # ArgoCD Application: ingress-nginx Helm release
β
βββ apps/
βββ demo/ # Helm chart for the demo nginx app
βββ Chart.yaml
βββ values.yaml # Default values (production-ish baseline)
βββ values-local.yaml # Local overrides (smaller resources, demo.local host)
βββ templates/
βββ deployment.yaml
βββ service.yaml
βββ ingress.yaml
- Create a Helm chart under
apps/<your-app>/:
apps/your-app/
βββ Chart.yaml
βββ values.yaml # sensible defaults, treat as prod baseline
βββ values-local.yaml # local overrides
βββ templates/
βββ ...
- Add an ArgoCD Application in
clusters/local/your-app.yml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: your-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/IntegratedDynamic/gitops.git
targetRevision: main
path: apps/your-app
helm:
valueFiles:
- values-local.yaml
destination:
server: https://kubernetes.default.svc
namespace: your-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueArgoCD picks it up automatically β no manual sync needed.
Say you're adding staging:
-
Add environment values for each app that needs overrides:
apps/demo/values-staging.yaml -
Add platform tools for the new cluster:
platform/staging/ingress-nginx.yml # e.g. with LoadBalancer instead of NodePort -
Add cluster entry point in
clusters/staging/:clusters/staging/demo.yml # same structure as local, different valueFiles clusters/staging/platform.yml # points to platform/staging/ -
Add a bootstrap manifest in
bootstrap/:bootstrap/staging.yaml # same structure as local.yaml, points to clusters/staging/ -
Point Terraform (or your cluster provisioner) at
bootstrap/staging.yamlto seed it.
Only the values files and cluster entry points differ β the charts themselves are never duplicated.
Platform tools are ArgoCD Applications that install Helm charts from external repositories.
Add a file per tool under platform/<env>/:
# platform/local/cert-manager.yml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.jetstack.io
chart: cert-manager
targetRevision: v1.17.0
helm:
values: |
installCRDs: true
destination:
server: https://kubernetes.default.svc
namespace: cert-manager
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueThe platform App-of-Apps picks it up automatically.
After mise run reset && mise run dev in the infrastructure repo:
# Add demo.local to /etc/hosts
echo "$(minikube ip) demo.local" | sudo tee -a /etc/hosts
# Check it's up
curl http://demo.local