Argo CD doesn’t actually deploy Kustomize apps; it renders Kustomize manifests and then applies those rendered manifests to your cluster.
Let’s see this in action. Imagine you have a Kustomize project structured like this:
my-app/
├── base/
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
└── dev/
├── kustomization.yaml
└── ingress.yaml
base/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
base/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
overlays/dev/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesStrategicMerge:
- deployment-patch.yaml
- service-patch.yaml
overlays/dev/deployment-patch.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app # Must match the name in base
spec:
template:
spec:
containers:
- name: my-app # Must match the container name in base
image: nginx:1.21.0 # Overridden image
overlays/dev/service-patch.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-app-service # Must match the name in base
spec:
type: ClusterIP # Overridden service type
overlays/dev/ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
rules:
- host: dev.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
When you configure Argo CD to sync this application, you’d point it to the Git repository containing my-app and specify the path as my-app/overlays/dev. Argo CD then does the following:
- Fetches the Git repository: It clones the specified branch and revision.
- Invokes
kustomize build: Argo CD internally runskustomize build <path-to-overlay>(e.g.,kustomize build my-app/overlays/dev). This command reads thekustomization.yamlfile in the specified overlay directory. - Applies Kustomize logic: Kustomize merges the
resourcesfrom the base, applies the strategic merge patches (deployment-patch.yaml,service-patch.yaml), and includes the additional resource (ingress.yaml). - Generates final manifests: The output of
kustomize buildis a single YAML stream containing the complete, rendered Kubernetes manifests. - Applies manifests to the cluster: Argo CD takes these generated manifests and applies them to your Kubernetes cluster using
kubectl applyor its own internal diffing and patching mechanisms.
The key is that Argo CD doesn’t understand Kustomize in the way you might think. It’s not a Kustomize-native controller. It’s a GitOps tool that knows how to execute Kustomize to produce standard Kubernetes YAML, and then it manages the lifecycle of those YAML objects in your cluster.
The problem this solves is a common one: managing application configurations that vary across environments (dev, staging, prod) without duplicating large amounts of YAML. Kustomize’s declarative approach allows you to define a common "base" and then apply environment-specific modifications (patches, additions) without forking the entire configuration. Argo CD then automates the deployment of these Kustomize-generated configurations from Git.
You control the behavior by defining your Kustomize structure. The kustomization.yaml file is the heart of it.
resources: Points to other Kustomize directories or raw YAML files that form the base configuration.patchesStrategicMerge: Applies patches to existing resources defined inresources. The patch file must have the sameapiVersion,kind,metadata.name, andmetadata.namespaceas the resource it’s patching.patchesJson6902: Allows for more precise JSON patch operations.commonLabels,commonAnnotations: Apply labels or annotations to all resources defined in thekustomization.yaml.images: Allows you to override image tags or names for all containers within the Kustomize build.
When you configure an Argo CD Application to use Kustomize, you provide the Git repository URL, the branch, and the path within the repository that contains the Kustomize kustomization.yaml file. Argo CD automatically detects that it’s a Kustomize project (based on the presence of kustomization.yaml) and performs the build step.
The one thing most people don’t realize is that Argo CD’s Kustomize integration is essentially a thin wrapper around the kustomize CLI. If you can build your manifests locally with kustomize build ./my-app/overlays/dev, Argo CD can deploy it. This means you can use any valid Kustomize feature, including complex plugins, and Argo CD will execute them as part of its build process. The rendered output is what Argo CD actually applies.
The next concept you’ll likely encounter is managing Helm charts alongside Kustomize applications within Argo CD, or exploring more advanced Kustomize features like server-side apply compatibility.