Flux has a feature called manifest generation that works together with Kustomize. Instead of just picking YAML files from a git repo and applying them, customisation is performed with the kustomize build command. The resulting YAML then gets applied to your cluster.
If you don’t know how customisation works (without Flux), take a look at the article I wrote earlier. Or look at the core docs.
You need to be aware of a few things before you get started. In order for Flux to use this method, you need to turn on manifest generation. With the Flux Helm chart, just pass the following parameter:
--set manifestGeneration=true
In my case, I have plain YAML files without customisation in a config folder. I want the files that use customisation in a different folder, say kustomize, like so:

To pass these folders to the Helm chart, use the following parameter:
--set git.path="config\,kustomize"
The kustomize folder contains the following files:

There is nothing special about the base folder here. It is as explained in my previous post. The dev and prod folders are similar so I will focus only on dev.
The dev folder contains a .flux.yaml file, which is required by Flux. In this simple example, it contains the following:
version: 1 patchUpdated: generators: - command: kustomize build . patchFile: flux-patch.yaml
The file specifies the generator to use, in this case Kustomize. The kustomize executable is in the Flux image. I specify one patchFile which contains patches for several resources separated by —:
--- apiVersion: apps/v1 kind: Deployment metadata: annotations: flux.weave.works/automated: "true" flux.weave.works/tag.realtime: semver:~1 name: realtime namespace: realtime-dev spec: template: spec: $setElementOrder/containers: - name: realtime containers: - image: gbaeke/fluxapp:1.0.6 name: realtime --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: realtime-ingress namespace: realtime-dev spec: rules: - host: realdev.baeke.info http: paths: - backend: serviceName: realtime servicePort: 80 path: / tls: - hosts: - realdev.baeke.info secretName: real-dev-baeke-info-tls
Above, you see the patches for the dev environment:
- the workload should be automated by Flux, installing new images based on the semantic version filter ~1
- the ingress should use host realdev.baeke.info with a different name for the secret as well (the secret will be created by cert-manager)
The prod folder contains a similar configuration. Perhaps naively, I thought that specifying the kustomize folder in git.path was sufficient for Flux to scan the folders and run customisation wherever a .flux.yaml file was found. Sadly, that is not the case. ☹️With just the kustomization folder specified, Flux find conflicts between base, dev and prod folders because they contain similar files. That is expected behaviour for regular YAML files but , in my opinion, should not happen in this case. There is a bit of a clunky way to make this work though. Just specify the following as git.path:
--set git.path="config\,kustomize/dev\,kustomize/prod"
With the above parameter, Flux will find no conflicts and will happily apply the customisations.
As a side note, you should also specify the namespace in the patch file explicitly. It is not added automatically even though kustomization.yaml contains the namespace.
Let’s look at the cluster when Flux has applied the changes.
And here is the deployed “production app”:

The way customisations are handled could be improved. It’s unwieldy to specify every “customisation” folder in the git.path parameter. Just give me a –git-kustomize-path parameter and scan the paths in that parameter for .flux.yaml files. On the other hand, maybe I am missing something here so remarks are welcome.