Skip to content

Commit 79841bb

Browse files
authored
Merge pull request #169 from projectsyn/explanation/kustomization-best-practices
Add best practices guide for using kustomizations in Commodore components
2 parents c27d953 + 7aab57a commit 79841bb

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ include::steward:ROOT:partial$nav-reference.adoc[]
9494
** xref:explanations/commodore-components/major.adoc[Major changes]
9595
** xref:explanations/commodore-components/secrets.adoc[User-provided Secrets]
9696
** xref:explanations/commodore-components/helm-charts.adoc[Using Helm charts]
97+
** xref:explanations/commodore-components/kustomizations.adoc[Using kustomizations]
9798
** xref:explanations/commodore-components/parameters-logic.adoc[Conditionals in the parameters hierarchy]
9899
** xref:explanations/commodore-components/crds.adoc[Custom Resource Defintions]
99100
** xref:explanations/commodore-components/alerts.adoc[Writing Prometheus Alert Rules]
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
= Using kustomizations in Commodore components
2+
3+
[IMPORTANT]
4+
====
5+
To use kustomizations, a `kustomize` binary must be present on the system.
6+
====
7+
8+
It's considered best practice to expose kustomization inputs to the user by introducing a component parameter `kustomize_input`
9+
10+
This minimizes the need for duplicated parameters between the kustomization configuration and the component default parameters.
11+
12+
Additionally, it's considered best practice to expose the kustomization URL in parameter `kustomization_url` and the kustomization version (if applicable) in parameter `manifests_version`.
13+
14+
Finally, it's considered best practice to expose the container images used by the kustomization as documented in the xref:explanations/commodore-components/container-images.adoc[container image versions] best practice documentation.
15+
16+
We recommend that the component renders an overlay which refers to the kustomization in Jsonnet, and calls `kustoize build` on the resulting YAML file.
17+
18+
19+
== Example
20+
21+
In this example, we present a fictional component `slo` which renders a kustomization for `fancy-sli-controller`.
22+
23+
24+
In `class/defaults.yml`, we provide the parameters to use when rendering the kustomization, as discussed above.
25+
26+
.class/defaults.yml
27+
[source,yaml]
28+
----
29+
parameters:
30+
slo:
31+
namespace: syn-slo
32+
kustomization_url: https://syn.example.com/fancy-sli-controller//config/default <1>
33+
manifests_version: '1.0.0'
34+
images:
35+
fancy-sli-controller:
36+
registry: quay.io
37+
repository: syn/fancy-sli-controller
38+
tag: '1.0.0'
39+
kustomize_input:
40+
namePrefix: syn-slo-
41+
namespace: ${slo:namespace}
42+
----
43+
<1> If the kustomization is stored in a subpath of the repository, use `//` to separate the repository URL from the path inside the repository.
44+
45+
In `component/fancy-sli-controller-overlay.jsonnet`, we render a `kustomization.yaml` which refers to the kustomization specified in `class/defaults.yml` and ensures the resulting Kubernetes resources use the image registry, repository and tags as specified in the parameters.
46+
We also merge the provided `kustomize_input` into the `kustomization.yaml`.
47+
This allows users to make arbitrary changes to the kustomization.
48+
49+
.component/fancy-sli-controller-overlay.jsonnet
50+
[source,jsonnet]
51+
----
52+
// Template to render kustomization overlay
53+
local com = import 'lib/commodore.libjsonnet';
54+
local kap = import 'lib/kapitan.libjsonnet';
55+
56+
local inv = kap.inventory();
57+
local params = inv.parameters.slo;
58+
59+
local image = params.images.fancy_sli_controller;
60+
61+
com.Kustomization( <1>
62+
params.kustomization_url,
63+
params.manifests_version,
64+
{
65+
'quay.io/syn/fancy-sli-controller': {
66+
newTag: image.tag,
67+
newName: '%(registry)s/%(repository)s' % image,
68+
},
69+
},
70+
params.kustomize_input,
71+
)
72+
----
73+
<1> This function generates an object which is suitable as a Jsonnet output.
74+
The resulting output will consist of a single `kustomization.yaml` file which is suitable as a `kustomize build` input.
75+
The provided `kustomization_url` and `manifests_version` will be rendered as an entry in the kustomization's `resource` field.
76+
The contents of the third parameter will be used to render entries for the kustomization's `images` field.
77+
See the xref:commodore:ROOT:reference/commodore-libjsonnet.adoc#_kustomizationbase_url_base_version_images_kustomize_input[`commodore.libjsonnet`] documentation for details.
78+
79+
In `class/slo.yml`, we render the `kustomization.yaml` and pass it `kustomize build` to generate the Kubernetes resources to commit to the cluster catalog.
80+
81+
.class/slo.yml
82+
[source,yaml]
83+
----
84+
parameters:
85+
kapitan:
86+
inputs:
87+
# render kustomization overlay into <component dir>/fancy-sli-controller
88+
- input_paths:
89+
- ${_base_directory}/component/fancy-sli-controller-overlay.jsonnet
90+
input_type: jsonnet
91+
output_path: ${_base_directory}/fancy-sli-controller
92+
93+
# Run kustomize on the rendered overlay.
94+
# NOTE: Kapitan ignores `output_path` for `input_type=external`
95+
- input_type: external
96+
output_path: .
97+
input_paths:
98+
- ${_kustomize_wrapper} <1>
99+
env_vars:
100+
INPUT_DIR: ${_base_directory}/fancy-sli-controller <2>
101+
args:
102+
- \${compiled_target_dir}/${_instance}/fancy-sli-controller-deployment <3>
103+
<4>
104+
105+
# Finally, delete the kustomize overlay which we rendered, so it doesn't
106+
# accidentally get committed to the component repository.
107+
- input_paths:
108+
- ${_base_directory}/fancy-sli-controller
109+
input_type: remove
110+
output_path: .
111+
----
112+
<1> The input path for `input_type=external` is the path to the external binary to call.
113+
Commodore provides parameter `_kustomize_wrapper` which expands to the absolute path of the Kustomize wrapper script which is distributed with Commodore.
114+
The wrapper script always executes `kustomize build`.
115+
<2> The Commodore kustomize wrapper expects the input directory in environment variable `INPUT_DIR`.
116+
<3> The Commodore wrapper script requires the first argument to be the output directory for `kustomize`.
117+
This allows us to avoid having to reimplement Kustomize's argument parsing in the wrapper script to find the output directory.
118+
+
119+
[IMPORTANT]
120+
====
121+
Always use `\${compiled_target_dir}` in the output path to ensure the generated Kubernetes resources are written to the Kapitan compilation target directory.
122+
This is a special variable which Kapitan substitutes with the absolute path of the target directory into which the component is compiled for compile steps with `input_type=external`.
123+
To ensure the variable is passed as `${compiled_target_dir}` to Kapitan, we must escape it to ensure it's not treated as a reclass variable.
124+
====
125+
<4> Users can provide arbitrary further arguments after the output directory which are passed to `kustomize` verbatim.
126+
Check `kustomize build --help` for supported arguments.

0 commit comments

Comments
 (0)