Skip to content

Drift Protection#

Examples of configuring Template.spec.sync to control drift on rendered resources. For the three modes, the comparison rules, and what each one does internally, see Sync.

Cert-manager prerequisite

sync.mode: strict requires cert-manager to be installed on the cluster, since the operator's validating webhook needs TLS. The Helm chart provisions a self-signed Issuer and a Certificate, but it does not install cert-manager itself.

Scenario 1: enforce a baseline NetworkPolicy (strict)#

Bill wants to publish a NetworkPolicy that consumers cannot edit or delete by hand. Strict mode rejects unauthorized edits at the API server.

apiVersion: templates.v2.stakater.com/v2alpha1
kind: Template
metadata:
  name: tenant-network-policy
  namespace: provider
spec:
  gotemplate: |
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-cross-tenant
    spec:
      podSelector: {}
      policyTypes: [Ingress]
      ingress:
        - from:
            - namespaceSelector:
                matchLabels:
                  kind: tenant
  sync:
    mode: strict

An attempt by a consumer to kubectl edit the rendered NetworkPolicy is rejected by the admission webhook with a message that points back at the owning TemplateInstance. The operator's own reconciles pass through unhindered.

Scenario 2: keep a Deployment in sync but let HPA scale it (revert + ignoreFields)#

Bill publishes a Deployment and wants the rendered shape preserved on every reconcile, but Anna runs a HorizontalPodAutoscaler against it. Strict mode would block HPA's updates to spec.replicas. Revert mode plus ignoreFields is the right tool.

spec:
  gotemplate: |
    apiVersion: apps/v1
    kind: Deployment
    ...
  sync:
    mode: revert
    ignoreFields:
      - spec.replicas
      - metadata.annotations

The controller reverts any drift in the rest of the Deployment spec on the next reconcile, but leaves spec.replicas and metadata.annotations to whoever last wrote them.

Scenario 3: bootstrap a resource that another controller will own (off)#

Bill publishes a Certificate for cert-manager to rotate. After cert-manager picks it up, it rewrites the associated Secret's data field on rotation. The default sync.mode: off is what Bill wants:

spec:
  gotemplate: |
    apiVersion: cert-manager.io/v1
    kind: Certificate
    ...
  # sync omitted -> mode defaults to off

Resources are applied once and then left alone: after the first clean apply the instance freezes, and neither Template nor TemplateInstance changes re-apply anything (see Sync).

Verifying that sync is active#

When sync.mode is revert or strict, the TemplateInstance reports a Synced condition:

status:
  conditions:
    - type: Synced
      status: "True"
      reason: SyncActive

The Ready condition continues to reflect overall reconciliation success.

Disabling sync without unbinding resources#

Changing Template.spec.sync.mode back to off (or removing spec.sync entirely) releases the drift watches on the next reconcile. The rendered resources stay in place; they are no longer enforced.

See also#