Skip to content

Commit 244b8b4

Browse files
committed
Added onfiguring Applications and Components as Code with Kustomize
1 parent b96547a commit 244b8b4

File tree

1 file changed

+350
-3
lines changed

1 file changed

+350
-3
lines changed
Lines changed: 350 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,351 @@
1-
= Configuration as code
1+
= Configuring Applications and Components as Code with Kustomize
22

3-
+
4-
NOTE: Is this topic needed or can it be rolled into index.adoc?
3+
If you want to define a large application with many components, easily duplicate or update components, or ensure consistent component and application states, you may want to configure your Konflux applications and components as code through Kustomize. This document provides an overview of a basic application and component configuration that can be replicated and duplicated using Kustomize bases and overlays. You can learn more about Kustomize at the following link: https://kustomize.io/[here]. This document is based on the configuration defined in the following repository: https://github.com/konflux-ci/casc-gpt[this repository]. You can see the configuration first-hand there.
4+
5+
Key steps include:
6+
7+
. **Create a basic file structure for your bases and overlays:** Prepare a space and structure for your application and component bases and overlays.
8+
9+
. **Create a base for your components:** Prepare a base that contains all the default or common values for every component you create.
10+
11+
. **Create a base for your application:** Prepare a base that contains all the default or common values for every application you create.
12+
13+
. **Create an overlay for each component:** Prepare an overlay that patches in component-specific data for each component in your application.
14+
15+
. **Create an overlay for your application:** Prepare an overlay that patches in specific data for each application you want to create.
16+
17+
. **Create patches for application-specific component configurations:** Prepare application-specific patches for all components in a given application, accommodating variations in specific patches.
18+
19+
. **Bonus - Duplicating or expanding your application:** Discuss the general philosophy of Configuration-as-Code and how to extend, duplicate, or customize your application, components, and workspace as code.
20+
21+
NOTE: Throughout this document, substitute your application and component names for placeholder values like `application-a`, `application-b`, `component-a`, etc.
22+
23+
== Create a File Structure
24+
25+
As with many Kustomize projects, you'll need a space to define a `base` and some `overlay`(s). Within your `overlay`(s), define a folder for a base set of components and a folder for each application-specific override for that base set of components.
26+
27+
Create a file structure as follows:
28+
29+
[source,bash]
30+
----
31+
├── base
32+
│ ├── component.yaml
33+
│ └── kustomization.yaml
34+
├── overlay
35+
│ └── application-a
36+
│ ├── base
37+
│ │ ├── application.yaml
38+
│ │ ├── component-a
39+
│ │ │ ├── component-a-override.yaml
40+
│ │ │ └── kustomization.yaml
41+
│ │ ├── component-b
42+
│ │ │ ├── component-b-override.yaml
43+
│ │ │ └── kustomization.yaml
44+
│ │ └── kustomization.yaml
45+
│ └── v1-overlay
46+
│ ├── application-patch.yaml
47+
│ ├── component-patch.yaml
48+
│ ├── exception-component-patch-1.yaml
49+
│ └── kustomization.yaml
50+
└── README.md
51+
----
52+
53+
NOTE: You can omit `component-b` if you only wish to define a single component.
54+
55+
In this file structure, you will find:
56+
57+
* `base`: A directory housing your base component YAML and a Kustomize file to point to the base.
58+
59+
* `overlay`: Contains one or more application variants, useful when defining multiple different applications.
60+
61+
* `overlay/application-a/base`: A base that defines one or more component overrides, one per component in the application, and a base for your application.
62+
63+
* `overlay/application-a/v1-overlay`: An override for your application and application-specific patches for your component(s).
64+
65+
== Create a Base for Your Components
66+
67+
If you are creating more than one component, it is likely that your components will share some, if not most, of their configuration. These default or global values can be defined in the base component and overridden on a case-by-case basis in your component overlays.
68+
69+
=== Creating Your Base Component
70+
71+
Define this base in `base/component.yaml`. It typically follows a pattern similar to the following:
72+
73+
[source,yaml]
74+
----
75+
apiVersion: appstudio.redhat.com/v1alpha1
76+
kind: Component
77+
metadata:
78+
annotations:
79+
image.redhat.com/generate: "true"
80+
appstudio.openshift.io/pac-provision: request
81+
build.appstudio.openshift.io/request: configure-pac
82+
name: example-component
83+
spec:
84+
componentName: example-component
85+
application: appName
86+
targetPort: 8080
87+
source:
88+
git:
89+
url: gitUrl
90+
context: ./
91+
dockerfileUrl: ContainerFileLocation
92+
revision: defaultBranch
93+
----
94+
95+
NOTE: This creates a component with a custom build pipeline. If you wish to use the default build, omit the `build.appstudio.openshift.io/request: configure-pac` annotation.
96+
97+
=== Creating Your Base Kustomization
98+
99+
With the base component defined, tell Kustomize it exists for later consumption in overlays. Set up a basic `base/kustomization.yaml` as follows:
100+
101+
[source,yaml]
102+
----
103+
apiVersion: kustomize.config.k8s.io/v1beta1
104+
kind: Kustomization
105+
106+
resources:
107+
- component.yaml
108+
----
109+
110+
== Create a Base for Your Application
111+
112+
Each application will have its own base and one or more overrides.
113+
114+
You can think of each application variant as the base that defines the structure of your application and all components in that application. The concrete application is an implementation of that variant that defines any differentiating specs, such as application name, version, and component branches.
115+
116+
Create your base application at `overlay/application-a/application-a-base/application.yaml` like the following:
117+
118+
[source,yaml]
119+
----
120+
apiVersion: appstudio.redhat.com/v1alpha1
121+
kind: Application
122+
metadata:
123+
name: base
124+
spec:
125+
description: base
126+
displayName: base
127+
----
128+
129+
And its Kustomization file at `overlay/application-a/application-a-base/kustomization.yaml`:
130+
131+
[source,yaml]
132+
----
133+
apiVersion: kustomize.config.k8s.io/v1beta1
134+
kind: Kustomization
135+
136+
resources:
137+
- application.yaml
138+
----
139+
140+
== Create an Overlay for Each Component
141+
142+
For each application, define every component in the application as an overlay. These overlays should contain all component-specific information that is consistent across all versions of the application, in case you have more than one version of the application.
143+
144+
For example, you'll typically have more than one version defined if you're developing a versioned operator and have consistent component names across every version of an application, but different branches (this is the OpenShift / OpenShift CI Model with release-versioned branches).
145+
146+
Define these components as folders in `overlay/application-a/base`. Each folder should be named after its component name, e.g., `component-a`, and contain an `override.yaml` and `kustomization.yaml` that look like:
147+
148+
`overlay/application-a/base/component-a/component-a-override.yaml` (replacing name, URL, and Dockerfile):
149+
150+
[source,yaml]
151+
----
152+
- op: replace
153+
path: /metadata/name
154+
value: component-a-name
155+
- op: replace
156+
path: /spec/componentName
157+
value: component-a-name
158+
- op: replace
159+
path: /spec/source/git/url
160+
value: https://myvcs.com/myorg/component-a
161+
- op: replace
162+
path: /spec/source/git/dockerfileUrl
163+
value: "Dockerfile"
164+
----
165+
166+
`overlay/application-a/base/component-a/kustomization.yaml`:
167+
168+
[source,yaml]
169+
----
170+
apiVersion: kustomize.config.k8s.io/v1beta1
171+
kind: Kustomization
172+
173+
resources:
174+
- ../../../../base # Path to base component
175+
176+
patches:
177+
- path: component-a-override.yaml # Path to override file
178+
target:
179+
kind: Component
180+
----
181+
182+
NOTE: You can repeat this pattern for every component in your application.
183+
184+
== Create an Overlay for Your Application and Application-Specific Component Configuration
185+
186+
For each version or variant of your application, as configured in the prior steps, define an application overlay and any additional application-specific component patches.
187+
188+
Version this concrete application and set of patches in its own overlay folder in the application folder. In this case, `overlay/application-a/v1-overlay` will hold:
189+
190+
* `application-patch.yaml`: Our application overlay
191+
192+
* `component-patch.yaml`: A version-specific patch for all components, typically a branch name
193+
194+
* `exception-component-patch.yaml`: An example version-specific patch for a specific component or set of components
195+
196+
* `kustomization.yaml`: A Kustomization file that defines how the patches are applied to components
197+
198+
Let's start with our `application-patch.yaml` at `overlay/application-a/v1-overlay/application-patch.yaml` (replacing values with your own):
199+
200+
[source,yaml]
201+
----
202+
- op: replace
203+
path: /metadata/name
204+
value: application-a-v1
205+
- op: replace
206+
path: /spec/description
207+
value: "Pipeline for application-a v1"
208+
- op: replace
209+
path: /spec/displayName
210+
value: "application-a v1"
211+
----
212+
213+
Followed by our override for components at `overlay/application-a/v1-overlay/component-patch.yaml`:
214+
215+
[source,yaml]
216+
----
217+
- op: replace
218+
path: /spec/application
219+
value: application-a-v1 # Must match /metadata/name in application-patch.yaml
220+
- op: replace
221+
path: /spec/source/git/revision
222+
value: release-v1 # Replace with your target branch for all components
223+
----
224+
225+
If you have any patches specific to this application revision that only impact a certain component or set of components, define another patch as shown in `overlay/application-a/v1-overlay/exception-component-patch-1.yaml`:
226+
227+
[source,yaml]
228+
----
229+
- op: replace
230+
path: /spec/source/git/revision
231+
value: main # In this example, one of our components will build off of main, so we set it in a separate patch.
232+
----
233+
234+
Finally, set up your `overlay/application-a/v1-overlay/kustomization.yaml` to apply these patches correctly:
235+
236+
[source,yaml]
237+
----
238+
apiVersion: kustomize.config.k8s.io/v1beta1
239+
kind: Kustomization
240+
241+
nameSuffix: v1 # Add a suffix to all resource names in the application for uniqueness
242+
resources:
243+
- ../base
244+
245+
patches:
246+
- target:
247+
kind: Application
248+
path: application-patch.yaml
249+
- target:
250+
kind: Component
251+
path: component-patch.yaml
252+
- target:
253+
kind: Component
254+
name: component-b
255+
path: exception-component-patch-1.yaml
256+
----
257+
258+
NOTE: This Kustomization applies a suffix to all resources. We recommend doing this to ensure uniqueness and make it easier to identify components and applications.
259+
260+
NOTE: You can define more than one exceptional patch and match component names through regex.
261+
262+
== Defining Multiple Versions or Variants of an Application
263+
264+
If multiple versions of an application exist (as in versioned operators) or variants of applications that share some or all components, define multiple application overlays following the same pattern as above.
265+
266+
This results in a configuration that looks something like the following, with a folder for each version:
267+
268+
[source,bash]
269+
----
270+
├── base
271+
│ ├── component.yaml
272+
│ └── kustomization.yaml
273+
├── overlay
274+
│ └── application-a
275+
│ ├── base
276+
│ │ ├── application.yaml
277+
│ │ ├── component-a
278+
│ │ │ ├── component-a-override.yaml
279+
│ │ │ └── kustomization.yaml
280+
│ │ ├── component-b
281+
│ │ │ ├── component-b-override.yaml
282+
│ │ │ └── kustomization.yaml
283+
│ │ └── kustomization.yaml
284+
│ ├── v1-overlay
285+
│ │ ├── application-patch.yaml
286+
│ │ ├── component-patch.yaml
287+
│ │ ├── exception-component-patch-1.yaml
288+
│ │ └── kustomization.yaml
289+
│ └── v2-overlay
290+
│ ├── application-patch.yaml
291+
│ ├── component-patch.yaml
292+
│ ├── exception-component-patch-1.yaml
293+
│ └── kustomization.yaml
294+
└── README.md
295+
----
296+
297+
== Defining Multiple Applications
298+
299+
If you wish to define multiple applications with different sets of components and versions for each application, replicate the above configuration for `application-a` for a second application and include it as an additional application base and overlays in the `overlay` directory.
300+
301+
This is the preferred way to define multiple applications within an application category (e.g., operators) or family/product organization (e.g., Red Hat Advanced Cluster Management) as code because it allows you to make bulk configurations to your base component YAML (such as enabling multi-arch or labeling/ownership) in a single place, the component base, rather than multiple places.
302+
303+
If you follow this method to create an `application-b` composed of `component-c` and `component-d`, then your directory structure will look something like:
304+
305+
[source,bash]
306+
----
307+
├── base
308+
│ ├── component.yaml
309+
│ └── kustomization.yaml
310+
├── overlay
311+
│ ├── application-a
312+
│ │ ├── base
313+
│ │ │ ├── application.yaml
314+
│ │ │ ├── component-a
315+
│ │ │ │ ├── component-a-override.yaml
316+
│ │ │ │ └── kustomization.yaml
317+
│ │ │ ├── component-b
318+
│ │ │ │ ├── component-b-override.yaml
319+
│ │ │ │ └── kustomization.yaml
320+
│ │ │ └── kustomization.yaml
321+
│ │ ├── v1-overlay
322+
│ │ │ ├── application-patch.yaml
323+
│ │ │ ├── component-patch.yaml
324+
│ │ │ ├── exception-component-patch-1.yaml
325+
│ │ │ └── kustomization.yaml
326+
│ │ └── v2-overlay
327+
│ │ ├── application-patch.yaml
328+
│ │ ├── component-patch.yaml
329+
│ │ ├── exception-component-patch-1.yaml
330+
│ │ └── kustomization.yaml
331+
│ └── application-b
332+
│ ├── base
333+
│ │ ├── application.yaml
334+
│ │ ├── component-c
335+
│ │ │ ├── component-c-override.yaml
336+
│ │ │ └── kustomization.yaml
337+
│ │ ├── component-d
338+
│ │ │ ├── component-d-override.yaml
339+
│ │ │ └── kustomization.yaml
340+
│ │ └── kustomization.yaml
341+
│ └── v1-overlay
342+
│ ├── application-patch.yaml
343+
│ ├── component-patch.yaml
344+
│ ├── exception-component-patch-1.yaml
345+
│ └── kustomization.yaml
346+
└── README.md
347+
----
348+
349+
NOTE: You can also modify the project structure to fit your own needs by moving application bases and component definitions to different levels, but this configuration offers the most layered encapsulation across applications and application versions.
350+
351+
IMPORTANT: Managing multiple related components and applications can be challenging. Refer https://redhat-appstudio.github.io/docs.appstudio.io/Documentation/main/how-to-guides/proc_multiversion/ [Managing multiple software versions] to manage multiple related components and applications.

0 commit comments

Comments
 (0)