Skip to content

Commit 02e1e73

Browse files
committed
Add support for drift detection ignore rules
Signed-off-by: Dipti Pai <diptipai89@outlook.com>
1 parent 877e664 commit 02e1e73

File tree

9 files changed

+561
-2
lines changed

9 files changed

+561
-2
lines changed

api/v1/kustomization_types.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,13 @@ type KustomizationSpec struct {
192192
// The expressions are evaluated only when Wait or HealthChecks are specified.
193193
// +optional
194194
HealthCheckExprs []kustomize.CustomHealthCheck `json:"healthCheckExprs,omitempty"`
195+
196+
// DriftIgnoreRules is a list of rules for specifying which changes to ignore
197+
// during drift detection. These rules are applied to the resources managed
198+
// by the Kustomization and are used to exclude specific JSON pointer paths
199+
// from the drift detection and apply process.
200+
// +optional
201+
DriftIgnoreRules []DriftIgnoreRule `json:"driftIgnoreRules,omitempty"`
195202
}
196203

197204
// CommonMetadata defines the common labels and annotations.
@@ -205,6 +212,22 @@ type CommonMetadata struct {
205212
Labels map[string]string `json:"labels,omitempty"`
206213
}
207214

215+
// DriftIgnoreRule defines a rule to selectively disregard specific changes during
216+
// the drift detection process.
217+
type DriftIgnoreRule struct {
218+
// Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
219+
// consideration in a Kubernetes object.
220+
// +required
221+
Paths []string `json:"paths"`
222+
223+
// Target is a selector for specifying Kubernetes objects to which this
224+
// rule applies.
225+
// If Target is not set, the Paths will be ignored for all Kubernetes
226+
// objects within the manifest of the Kustomization.
227+
// +optional
228+
Target *kustomize.Selector `json:"target,omitempty"`
229+
}
230+
208231
// Decryption defines how decryption is handled for Kubernetes manifests.
209232
type Decryption struct {
210233
// Provider is the name of the decryption engine.

api/v1/zz_generated.deepcopy.go

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,73 @@ spec:
149149
- name
150150
type: object
151151
type: array
152+
driftIgnoreRules:
153+
description: |-
154+
DriftIgnoreRules is a list of rules for specifying which changes to ignore
155+
during drift detection. These rules are applied to the resources managed
156+
by the Kustomization and are used to exclude specific JSON pointer paths
157+
from the drift detection and apply process.
158+
items:
159+
description: |-
160+
DriftIgnoreRule defines a rule to selectively disregard specific changes during
161+
the drift detection process.
162+
properties:
163+
paths:
164+
description: |-
165+
Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
166+
consideration in a Kubernetes object.
167+
items:
168+
type: string
169+
type: array
170+
target:
171+
description: |-
172+
Target is a selector for specifying Kubernetes objects to which this
173+
rule applies.
174+
If Target is not set, the Paths will be ignored for all Kubernetes
175+
objects within the manifest of the Kustomization.
176+
properties:
177+
annotationSelector:
178+
description: |-
179+
AnnotationSelector is a string that follows the label selection expression
180+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
181+
It matches with the resource annotations.
182+
type: string
183+
group:
184+
description: |-
185+
Group is the API group to select resources from.
186+
Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources.
187+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
188+
type: string
189+
kind:
190+
description: |-
191+
Kind of the API Group to select resources from.
192+
Together with Group and Version it is capable of unambiguously
193+
identifying and/or selecting resources.
194+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
195+
type: string
196+
labelSelector:
197+
description: |-
198+
LabelSelector is a string that follows the label selection expression
199+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
200+
It matches with the resource labels.
201+
type: string
202+
name:
203+
description: Name to match resources with.
204+
type: string
205+
namespace:
206+
description: Namespace to select resources from.
207+
type: string
208+
version:
209+
description: |-
210+
Version of the API Group to select resources from.
211+
Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources.
212+
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
213+
type: string
214+
type: object
215+
required:
216+
- paths
217+
type: object
218+
type: array
152219
force:
153220
default: false
154221
description: |-

docs/api/v1/kustomize.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,23 @@ health of custom resources using Common Expression Language (CEL).
425425
The expressions are evaluated only when Wait or HealthChecks are specified.</p>
426426
</td>
427427
</tr>
428+
<tr>
429+
<td>
430+
<code>driftIgnoreRules</code><br>
431+
<em>
432+
<a href="#kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">
433+
[]DriftIgnoreRule
434+
</a>
435+
</em>
436+
</td>
437+
<td>
438+
<em>(Optional)</em>
439+
<p>DriftIgnoreRules is a list of rules for specifying which changes to ignore
440+
during drift detection. These rules are applied to the resources managed
441+
by the Kustomization and are used to exclude specific JSON pointer paths
442+
from the drift detection and apply process.</p>
443+
</td>
444+
</tr>
428445
</table>
429446
</td>
430447
</tr>
@@ -684,6 +701,57 @@ the feature gate <code>AdditiveCELDependencyCheck</code> must be set to <code>tr
684701
</table>
685702
</div>
686703
</div>
704+
<h3 id="kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">DriftIgnoreRule
705+
</h3>
706+
<p>
707+
(<em>Appears on:</em>
708+
<a href="#kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec</a>)
709+
</p>
710+
<p>DriftIgnoreRule defines a rule to selectively disregard specific changes during
711+
the drift detection process.</p>
712+
<div class="md-typeset__scrollwrap">
713+
<div class="md-typeset__table">
714+
<table>
715+
<thead>
716+
<tr>
717+
<th>Field</th>
718+
<th>Description</th>
719+
</tr>
720+
</thead>
721+
<tbody>
722+
<tr>
723+
<td>
724+
<code>paths</code><br>
725+
<em>
726+
[]string
727+
</em>
728+
</td>
729+
<td>
730+
<p>Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
731+
consideration in a Kubernetes object.</p>
732+
</td>
733+
</tr>
734+
<tr>
735+
<td>
736+
<code>target</code><br>
737+
<em>
738+
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#Selector">
739+
github.com/fluxcd/pkg/apis/kustomize.Selector
740+
</a>
741+
</em>
742+
</td>
743+
<td>
744+
<em>(Optional)</em>
745+
<p>Target is a selector for specifying Kubernetes objects to which this
746+
rule applies.
747+
If Target is not set, the Paths will be ignored for all Kubernetes
748+
objects within the manifest of the Kustomization.</p>
749+
</td>
750+
</tr>
751+
</tbody>
752+
</table>
753+
</div>
754+
</div>
687755
<h3 id="kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec
688756
</h3>
689757
<p>
@@ -1058,6 +1126,23 @@ health of custom resources using Common Expression Language (CEL).
10581126
The expressions are evaluated only when Wait or HealthChecks are specified.</p>
10591127
</td>
10601128
</tr>
1129+
<tr>
1130+
<td>
1131+
<code>driftIgnoreRules</code><br>
1132+
<em>
1133+
<a href="#kustomize.toolkit.fluxcd.io/v1.DriftIgnoreRule">
1134+
[]DriftIgnoreRule
1135+
</a>
1136+
</em>
1137+
</td>
1138+
<td>
1139+
<em>(Optional)</em>
1140+
<p>DriftIgnoreRules is a list of rules for specifying which changes to ignore
1141+
during drift detection. These rules are applied to the resources managed
1142+
by the Kustomization and are used to exclude specific JSON pointer paths
1143+
from the drift detection and apply process.</p>
1144+
</td>
1145+
</tr>
10611146
</tbody>
10621147
</table>
10631148
</div>

docs/spec/v1/kustomizations.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,120 @@ kustomize.toolkit.fluxcd.io/force: enabled
854854
This way, only the targeted resources are force-replaced when immutable field
855855
changes are made. The annotation should be removed after the change is applied.
856856

857+
### Drift Ignore Rules
858+
859+
`.spec.driftIgnoreRules` is an optional list used to selectively ignore changes
860+
to specific fields during drift detection and correction. This allows external
861+
controllers or tools to manage certain fields on Kubernetes resources without
862+
having those changes reverted by the kustomize-controller during reconciliation.
863+
864+
Each item in the list must have the following fields:
865+
866+
- `paths` (required): A list of [JSON Pointer (RFC 6901)](https://datatracker.ietf.org/doc/html/rfc6901)
867+
paths to exclude from drift detection. These paths refer to specific fields
868+
within the Kubernetes object manifest.
869+
- `target` (optional): A selector to scope the rule to specific Kubernetes
870+
resources. If not set, the paths are ignored for all resources in the
871+
Kustomization.
872+
873+
**Warning:** Omitting the `target` selector causes the rule to match **all**
874+
objects managed by the Kustomization. Always scope rules to specific resources
875+
using `target` unless you intentionally want to ignore the specified paths
876+
across every resource.
877+
878+
The `target` selector supports the following fields:
879+
880+
| Field | Description |
881+
|----------------------|--------------------------------------|
882+
| `group` | API group (regex) |
883+
| `version` | API version (regex) |
884+
| `kind` | Resource kind (regex) |
885+
| `name` | Resource name (regex) |
886+
| `namespace` | Resource namespace (regex) |
887+
| `labelSelector` | Kubernetes label selector expression |
888+
| `annotationSelector` | Kubernetes annotation selector expression |
889+
890+
**Note:** The `group`, `version`, `kind`, `name`, and `namespace` fields
891+
support regex patterns. The `labelSelector` and `annotationSelector` fields
892+
use the standard Kubernetes
893+
[label selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors)
894+
syntax.
895+
896+
**Note:** For JSON Pointer paths that contain `/` in the key name (e.g.
897+
annotation keys), the `/` must be escaped as `~1` per
898+
[RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901#section-3).
899+
For example, the annotation `external-dns.alpha.kubernetes.io/hostname`
900+
would be referenced as `/metadata/annotations/external-dns.alpha.kubernetes.io~1hostname`.
901+
902+
#### Ignore a field on all resources
903+
904+
To ignore a specific field on all resources managed by the Kustomization:
905+
906+
```yaml
907+
---
908+
apiVersion: kustomize.toolkit.fluxcd.io/v1
909+
kind: Kustomization
910+
metadata:
911+
name: app
912+
namespace: flux-system
913+
spec:
914+
# ...omitted for brevity
915+
driftIgnoreRules:
916+
- paths:
917+
- "/spec/replicas"
918+
```
919+
920+
#### Ignore fields on specific resources
921+
922+
To ignore fields only on resources that match a target selector:
923+
924+
```yaml
925+
---
926+
apiVersion: kustomize.toolkit.fluxcd.io/v1
927+
kind: Kustomization
928+
metadata:
929+
name: app
930+
namespace: flux-system
931+
spec:
932+
# ...omitted for brevity
933+
driftIgnoreRules:
934+
- paths:
935+
- "/spec/replicas"
936+
target:
937+
kind: Deployment
938+
- paths:
939+
- "/metadata/annotations/external-dns.alpha.kubernetes.io~1hostname"
940+
target:
941+
kind: Service
942+
name: my-service
943+
- paths:
944+
- "/spec/template/spec/containers/0/resources"
945+
target:
946+
kind: Deployment
947+
name: my-app
948+
```
949+
950+
In the above example:
951+
952+
- The `/spec/replicas` field is ignored on all Deployments, allowing
953+
an HPA or other autoscaler to manage the replica count without
954+
interference from the kustomize-controller.
955+
- The `external-dns.alpha.kubernetes.io/hostname` annotation is ignored
956+
on a specific Service named `my-service`, allowing external-dns to
957+
manage this annotation.
958+
- The entire `/resources` subtree under container spec is ignored on
959+
a specific Deployment named `my-app`, allowing a VPA or other resource
960+
management tool to adjust container resources.
961+
962+
**Important:** Drift ignore rules work with the
963+
[server-side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/)
964+
field ownership model. The ignored paths are removed from the desired state
965+
before the controller applies, which relinquishes the controller's ownership of
966+
those fields. For the ignored fields to be preserved, they must be owned by
967+
another field manager (e.g. another controller or a `kubectl apply --server-side
968+
--field-manager=<name>` invocation). If no other field manager owns the field,
969+
the API server may remove it during garbage collection of abandoned fields.
970+
857971
### KubeConfig (Remote clusters)
858972

859973
With the `.spec.kubeConfig` field a Kustomization

0 commit comments

Comments
 (0)