[builtin operations]: ../docs/plugins/builtins.md [builtin plugins]: ../docs/plugins/builtins.md [plugins]: ../docs/plugins [plugin]: ../docs/plugins [fields]: ../docs/fields.md [fields in a kustomization file]: ../docs/fields.md [TransformerConfig]: ../api/internal/plugins/builtinconfig/transformerconfig.go [kustomization]: ../docs/glossary.md#kustomization # Customizing kustomize The [fields in a kustomization file] allow the user to specify which resource files to use as input, how to _generate_ new resources, and how to _transform_ those resources - add labels, patch them, etc. These fields are simple (low argument count) directives. For example, the `commonAnnotations` field demands only a list of _name:value_ pairs. If using a field triggers behavior that pleases the user, everyone's happy. If not, the user can ask for new behavior to be implemented in kustomize proper (and wait), or the user can write a transformer or generator [plugin]. This latter option generally means writing code; a Go plugin, a Go binary, a C++ binary, a `bash` script - something. There's a third option. If one merely wants to tweak behavior that already exists in kustomize, one may be able to do so by just writing some YAML. ## Configure the builtin plugins All of kustomize's [builtin operations] are implemented and usable as plugins. Using the fields is convenient and brief, but necessarily specifies only part of the entire plugin specification. The unspecified part is defaulted to what are hopefully generally appealing values. If, instead, one invokes the plugins directly using the `transformers` or `generators` field, one can (indeed _must_) specify the entire plugin configuration. ## Example: field vs plugin Define a place to work: ``` DEMO_HOME=$(mktemp -d) ``` ### Using the `commonLabels` and `commonAnnotations` fields In this simple example, we'll use just two resources: a deployment and a service. Define them: ``` cat <$DEMO_HOME/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment spec: replicas: 10 template: spec: containers: - name: the-container image: monopole/hello:1 EOF ``` ``` cat <$DEMO_HOME/service.yaml apiVersion: v1 kind: Service metadata: name: service spec: type: LoadBalancer ports: - protocol: TCP port: 8666 targetPort: 8080 EOF ``` Now make a kustomization file that causes them to be read and transformed: ``` cat <<'EOF' >$DEMO_HOME/kustomization.yaml namePrefix: hello- commonLabels: app: hello commonAnnotations: area: "51" greeting: Take me to your leader resources: - deployment.yaml - service.yaml EOF ``` And run kustomize: ``` kustomize build $DEMO_HOME ``` The output will be something like > ``` > apiVersion: v1 > kind: Service > metadata: > annotations: > area: "51" > greeting: Take me to your leader > labels: > app: hello > name: hello-service > spec: > ports: > - port: 8666 > protocol: TCP > targetPort: 8080 > selector: > app: hello > type: LoadBalancer > --- > apiVersion: apps/v1 > kind: Deployment > metadata: > annotations: > area: "51" > greeting: Take me to your leader > labels: > app: hello > name: hello-deployment > spec: > replicas: 10 > selector: > matchLabels: > app: hello > template: > metadata: > annotations: > area: "51" > greeting: Take me to your leader > labels: > app: hello > spec: > containers: > - image: monopole/hello:1 > name: the-container > ``` Let's say we are unhappy with this result. We only want the annotations to be applied down in the pod templates, and don't want to see them in the metadata for Service or Deployment. We like that the label _app: hello_ ended up in - Service `spec.selector` - Deployment `spec.selector.matchLabels` - Deployment `spec.template.metadata.labels` as this binds the Service (load balancer) to the pods, and the Deployment itself to its own pods - but we again don't care to see these labels in the metadata for the Service and the Deployment. ### Configuring the builtin plugins instead To fine tune this, invoke the same transformations using the plugin approach. Change the kustomization file: ``` cat <<'EOF' >$DEMO_HOME/kustomization.yaml namePrefix: hello- transformers: - myAnnotator.yaml - myLabeller.yaml resources: - deployment.yaml - service.yaml EOF ``` Then make the two plugin configuration files (`myAnnotator.yaml`, `myLabeller.yaml`) referred to by the `transformers` field above. For details about the fields to specify, see the documentation for the [builtin plugins]. ``` cat <$DEMO_HOME/myAnnotator.yaml apiVersion: builtin kind: AnnotationsTransformer metadata: name: notImportantHere annotations: area: 51 greeting: take me to your leader fieldSpecs: - kind: Deployment path: spec/template/metadata/annotations create: true EOF ``` ``` cat <$DEMO_HOME/myLabeller.yaml apiVersion: builtin kind: LabelTransformer metadata: name: notImportantHere labels: app: hello fieldSpecs: - kind: Service path: spec/selector create: true - kind: Deployment path: spec/selector/matchLabels create: true - kind: Deployment path: spec/template/metadata/labels create: true EOF ``` Finally, run kustomize again: ``` kustomize build $DEMO_HOME ``` The output should resemble the following, with fewer labels and annotations. > ``` > apiVersion: v1 > kind: Service > metadata: > name: hello-service > spec: > ports: > - port: 8666 > protocol: TCP > targetPort: 8080 > selector: > app: hello > type: LoadBalancer > --- > apiVersion: apps/v1 > kind: Deployment > metadata: > name: hello-deployment > spec: > replicas: 10 > selector: > matchLabels: > app: hello > template: > metadata: > annotations: > area: "51" > greeting: take me to your leader > labels: > app: hello > spec: > containers: > - image: monopole/hello:1 > name: the-container > ``` ## The old way to do this The original (and still functional) way to customize kustomize is to specify a `configurations` field in the kustomization file. This field, normally omitted because it overrides hardcoded data, accepts a list of file path arguments. The files, in turn, specify which fields in which k8s objects should be affected by particular builtin transformations. It's a global configuration cutting across transformations, and doesn't effect generators at all. At `build` time, the configuration files are unmarshalled into one instance of [TransformerConfig]. This object, _plus_ the field values for `namePrefix`, etc. are fed into the transformation code to build the output. The best way to write these custom configuration files is to generate the files from the hardcoded values built into kustomize via these commands: > ``` > mkdir /tmp/junk > kustomize config save -d /tmp/junk > ``` One can then edit those file or files, and specify the resulting edited files in a `configurations:` field in a kustomization file used in a `build`. Using plugins _completely ignores_ both hard coded tranformer configuration, and any configuration loaded by the `configuration` field.