Kustomize

Declarative

You can define a Kustomize application manifest in the declarative GitOps way. Here is an example:

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Application
  3. metadata:
  4. name: kustomize-example
  5. spec:
  6. project: default
  7. source:
  8. path: examples/helloWorld
  9. repoURL: 'https://github.com/kubernetes-sigs/kustomize'
  10. targetRevision: HEAD
  11. destination:
  12. namespace: default
  13. server: 'https://kubernetes.default.svc'
  14. If the `kustomization.yaml` file exists at the location pointed to by `repoURL` and `path`, Argo CD will render the manifests using Kustomize.
  15. The following configuration options are available for Kustomize:
  16. * `namePrefix` is a prefix appended to resources for Kustomize apps
  17. * `nameSuffix` is a suffix appended to resources for Kustomize apps
  18. * `images` is a list of Kustomize image overrides
  19. * `replicas` is a list of Kustomize replica overrides
  20. * `commonLabels` is a string map of additional labels
  21. * `labelWithoutSelector` is a boolean value which defines if the common label(s) should be applied to resource selectors and templates.
  22. * `forceCommonLabels` is a boolean value which defines if it's allowed to override existing labels
  23. * `commonAnnotations` is a string map of additional annotations
  24. * `namespace` is a Kubernetes resources namespace
  25. * `forceCommonAnnotations` is a boolean value which defines if it's allowed to override existing annotations
  26. * `commonAnnotationsEnvsubst` is a boolean value which enables env variables substition in annotation values
  27. * `patches` is a list of Kustomize patches that supports inline updates
  28. * `components` is a list of Kustomize components
  29. To use Kustomize with an overlay, point your path to the overlay.
  30. !!! tip
  31. If you're generating resources, you should read up how to ignore those generated resources using the [`IgnoreExtraneous` compare option](compare-options.md).
  32. ## Patches
  33. Patches are a way to kustomize resources using inline configurations in Argo CD applications. `patches` follow the same logic as the corresponding Kustomization. Any patches that target existing Kustomization file will be merged.
  34. This Kustomize example sources manifests from the `/kustomize-guestbook` folder of the `argoproj/argocd-example-apps` repository, and patches the `Deployment` to use port `443` on the container.
  35. ```yaml
  36. apiVersion: kustomize.config.k8s.io/v1beta1
  37. kind: Kustomization
  38. metadata:
  39. name: kustomize-inline-example
  40. namespace: test1
  41. resources:
  42. - https://github.com/argoproj/argocd-example-apps//kustomize-guestbook/
  43. patches:
  44. - target:
  45. kind: Deployment
  46. name: guestbook-ui
  47. patch: |-
  48. - op: replace
  49. path: /spec/template/spec/containers/0/ports/0/containerPort
  50. value: 443

This Application does the equivalent using the inline kustomize.patches configuration.

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Application
  3. metadata:
  4. name: kustomize-inline-guestbook
  5. namespace: argocd
  6. finalizers:
  7. - resources-finalizer.argocd.argoproj.io
  8. spec:
  9. destination:
  10. namespace: test1
  11. server: https://kubernetes.default.svc
  12. project: default
  13. source:
  14. path: kustomize-guestbook
  15. repoURL: https://github.com/argoproj/argocd-example-apps.git
  16. targetRevision: master
  17. kustomize:
  18. patches:
  19. - target:
  20. kind: Deployment
  21. name: guestbook-ui
  22. patch: |-
  23. - op: replace
  24. path: /spec/template/spec/containers/0/ports/0/containerPort
  25. value: 443

The inline kustomize patches work well with ApplicationSets, too. Instead of maintaining a patch or overlay for each cluster, patches can now be done in the Application template and utilize attributes from the generators. For example, with external-dns to set the txt-owner-id to the cluster name.

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: ApplicationSet
  3. metadata:
  4. name: external-dns
  5. spec:
  6. goTemplate: true
  7. goTemplateOptions: ["missingkey=error"]
  8. generators:
  9. - clusters: {}
  10. template:
  11. metadata:
  12. name: 'external-dns'
  13. spec:
  14. project: default
  15. source:
  16. repoURL: https://github.com/kubernetes-sigs/external-dns/
  17. targetRevision: v0.14.0
  18. path: kustomize
  19. kustomize:
  20. patches:
  21. - target:
  22. kind: Deployment
  23. name: external-dns
  24. patch: |-
  25. - op: add
  26. path: /spec/template/spec/containers/0/args/3
  27. value: --txt-owner-id={{.name}} # patch using attribute from generator
  28. destination:
  29. name: 'in-cluster'
  30. namespace: default

Components

Kustomize components encapsulate both resources and patches together. They provide a powerful way to modularize and reuse configuration in Kubernetes applications.

Outside of Argo CD, to utilize components, you must add the following to the kustomization.yaml that the Application references. For example:

  1. apiVersion: kustomize.config.k8s.io/v1beta1
  2. kind: Kustomization
  3. ...
  4. components:
  5. - ../component

With support added for components in v2.10.0, you can now reference a component directly in the Application:

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Application
  3. metadata:
  4. name: application-kustomize-components
  5. spec:
  6. ...
  7. source:
  8. path: examples/application-kustomize-components/base
  9. repoURL: https://github.com/my-user/my-repo
  10. targetRevision: main
  11. # This!
  12. kustomize:
  13. components:
  14. - ../component # relative to the kustomization.yaml (`source.path`).

Private Remote Bases

If you have remote bases that are either (a) HTTPS and need username/password (b) SSH and need SSH private key, then they’ll inherit that from the app’s repo.

This will work if the remote bases uses the same credentials/private key. It will not work if they use different ones. For security reasons your app only ever knows about its own repo (not other team’s or users repos), and so you won’t be able to access other private repos, even if Argo CD knows about them.

Read more about private repos.

kustomize build Options/Parameters

To provide build options to kustomize build of default Kustomize version, use kustomize.buildOptions field of argocd-cm ConfigMap. Use kustomize.buildOptions.<version> to register version specific build options.

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. kustomize.buildOptions: --load-restrictor LoadRestrictionsNone
  11. kustomize.buildOptions.v4.4.0: --output /tmp

After modifying kustomize.buildOptions, you may need to restart ArgoCD for the changes to take effect.

Custom Kustomize versions

Argo CD supports using multiple Kustomize versions simultaneously and specifies required version per application. To add additional versions make sure required versions are bundled and then use kustomize.path.<version> fields of argocd-cm ConfigMap to register bundled additional versions.

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. labels:
  7. app.kubernetes.io/name: argocd-cm
  8. app.kubernetes.io/part-of: argocd
  9. data:
  10. kustomize.path.v3.5.1: /custom-tools/kustomize_3_5_1
  11. kustomize.path.v3.5.4: /custom-tools/kustomize_3_5_4

Once a new version is configured you can reference it in an Application spec as follows:

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Application
  3. metadata:
  4. name: guestbook
  5. spec:
  6. source:
  7. repoURL: https://github.com/argoproj/argocd-example-apps.git
  8. targetRevision: HEAD
  9. path: kustomize-guestbook
  10. kustomize:
  11. version: v3.5.4

Additionally, the application kustomize version can be configured using the Parameters tab of the Application Details page, or using the following CLI command:

  1. argocd app set <appName> --kustomize-version v3.5.4

Build Environment

Kustomize apps have access to the standard build environment which can be used in combination with a config management plugin to alter the rendered manifests.

You can use these build environment variables in your Argo CD Application manifests. You can enable this by setting .spec.source.kustomize.commonAnnotationsEnvsubst to true in your Application manifest.

For example, the following Application manifest will set the app-source annotation to the name of the Application:

  1. apiVersion: argoproj.io/v1alpha1
  2. kind: Application
  3. metadata:
  4. name: guestbook-app
  5. namespace: argocd
  6. spec:
  7. project: default
  8. destination:
  9. namespace: demo
  10. server: https://kubernetes.default.svc
  11. source:
  12. path: kustomize-guestbook
  13. repoURL: https://github.com/argoproj/argocd-example-apps
  14. targetRevision: HEAD
  15. kustomize:
  16. commonAnnotationsEnvsubst: true
  17. commonAnnotations:
  18. app-source: ${ARGOCD_APP_NAME}
  19. syncPolicy:
  20. syncOptions:
  21. - CreateNamespace=true

Kustomizing Helm charts

It’s possible to render Helm charts with Kustomize. Doing so requires that you pass the --enable-helm flag to the kustomize build command. This flag is not part of the Kustomize options within Argo CD. If you would like to render Helm charts through Kustomize in an Argo CD application, you have two options: You can either create a custom plugin, or modify the argocd-cm ConfigMap to include the --enable-helm flag globally for all Kustomize applications:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: argocd-cm
  5. namespace: argocd
  6. data:
  7. kustomize.buildOptions: --enable-helm

Setting the manifests’ namespace

The spec.destination.namespace field only adds a namespace when it’s missing from the manifests generated by Kustomize. It also uses kubectl to set the namespace, which sometimes misses namespace fields in certain resources (for example, custom resources). In these cases, you might get an error like this: ClusterRoleBinding.rbac.authorization.k8s.io "example" is invalid: subjects[0].namespace: Required value.

Using Kustomize directly to set the missing namespaces can resolve this problem. Setting spec.source.kustomize.namespace instructs Kustomize to set namespace fields to the given value.

If spec.destination.namespace and spec.source.kustomize.namespace are both set, Argo CD will defer to the latter, the namespace value set by Kustomize.