Publications

Conditional Provisioning: When Conditions and the Two Enforcement Boundaries

*Orkestra Project — March 2026*

4 min read

Orkestra Project — March 2026


Abstract

Orkestra provides two mechanisms for controlling what resources exist in a cluster: when: conditions and admission rules. They are not alternatives to each other. They enforce different things at different boundaries, and understanding the distinction is what enables platform engineers to build expressive, correct operator topologies.


1. Two different questions

Admission rules answer: Should this CR exist?

When a Website CR with a non-compliant image is submitted, a deny rule answers: no, this CR should not be stored. The API server rejects it before it reaches etcd.

when: conditions answer: Given that this CR exists and is valid, which child resources should currently exist?

When a valid Website CR has spec.environment: staging, a when: condition can answer: the LoadBalancer Service and the PodDisruptionBudget should not exist.


2. Admission: enforcement at the boundary

Admission runs at the Kubernetes API server boundary.

Deny at admission:

validation:
  - field: spec.image
    prefix: "myorg/"
    message: "images must come from the internal registry"
    action: deny

If this rule fires, the API server returns an error to the client before the object is stored. The CR does not exist in the cluster.

Warn at admission:

The CR is stored. The user sees a warning in their kubectl output.


3. When conditions: enforcement at the resource level

when: conditions run inside the reconcile loop, evaluated per-resource, per-cycle.

onCreate:
  services:
    - name: "{{ .metadata.name }}-lb"
      type: LoadBalancer
      port: "443"
      when:
        - field: spec.environment
          equals: production    # only in production
        - field: spec.tlsEnabled
          operator: exists      # only when TLS is configured

When these conditions are not met, the LoadBalancer Service is not created. No error. No rejection. The reconcile succeeds. The CR is healthy.


4. The declarative topology pattern

The power of when: conditions is not in any single condition — it is in what conditions enable: an operator whose behavior changes continuously with the state of the CR, without any operator-side logic to manage that change.

Consider a Website CR that supports multiple deployment tiers:

onCreate:
  deployments:
    - name: "{{ .metadata.name }}"
      image: "{{ .spec.image }}"
      replicas: "{{ .spec.replicas }}"
      reconcile: true
      # Always created — every tier gets a Deployment

  services:
    - name: "{{ .metadata.name }}-lb"
      type: LoadBalancer
      port: "443"
      when:
        - field: spec.tier
          notEquals: free
      # Only for paid tiers — free tier gets no LoadBalancer

  configMaps:
    - name: "{{ .metadata.name }}-rate-limits"
      when:
        - field: spec.tier
          equals: enterprise
      # Enterprise rate limits — only for enterprise tier

When a user changes their Website CR from spec.tier: free to spec.tier: pro, the next reconcile cycle creates the LoadBalancer Service. When they upgrade to spec.tier: enterprise, the rate limit ConfigMap is created.

The operator’s topology changes with the data. No operator code changes. No redeployment.


6. Admission as the gate, conditions as the topology

The two mechanisms compose cleanly because they operate at different boundaries:

Admission ensures only valid, compliant CRs enter the cluster. It is the gate. Rules express invariants.

Conditions shape what a valid CR produces. They are the topology. They express contingent truths.

Together, they provide the full policy model.


7. When to use each

Use admission rules when the CR should not exist if the condition fails.

  • Image not from internal registry → CR should not be created
  • Missing required field → CR should not be created

Use when: conditions when the CR is valid but some resources should not exist given the current CR state.

  • Service type depends on environment (staging vs production)
  • Additional resources depend on optional spec fields
  • Resources depend on tier, plan, or feature flags in the CR

Conclusion

when: conditions and admission rules are two distinct and complementary enforcement mechanisms. Admission rules operate at the API server boundary and answer whether a CR should exist. Conditions operate at the reconcile boundary and answer what a valid CR should produce.

Understanding the boundary between these mechanisms is not a detail of Orkestra’s implementation. It is the conceptual foundation of declarative operator design.