This is a beta feature.

This feature was introduced in v1.14.
This feature graduated to beta status in v1.19.

For more information read the Crossplane feature lifecycle.

This document is for a preview version of Crossplane.

This document applies to Crossplane v2.0-preview and not to the latest release v1.19.

Don't use Crossplane v2.0-preview in production.

A Usage indicates a resource is in use. Two main use cases for Usages are as follows:

  1. Protecting a resource from accidental deletion.
  2. Deletion ordering by ensuring that a resource isn’t deleted before the deletion of its dependent resources.

See the section Usage for Deletion Protection for the first use case and the section Usage for Deletion Ordering for the second one.

Enable usages

Usages are a beta feature. Beta features are enabled by default.

Disable Usage support by changing the Crossplane pod setting and setting
--enable-usages=false argument.

 1$ kubectl edit deployment crossplane --namespace crossplane-system
 2apiVersion: apps/v1
 3kind: Deployment
 4spec:
 5# Removed for brevity
 6  template:
 7    spec:
 8      containers:
 9      - args:
10        - core
11        - start
12        - --enable-usages=false
Tip
The Crossplane install guide describes enabling feature flags like --enable-usages with Helm.

Create a usage

A Usage spec has a mandatory of field for defining the resource in use or protected. The reason field defines the reason for protection and the by field defines the using resource. Both fields are optional, but at least one of them must be provided.

Usage for deletion protection

The following example prevents the deletion of the my-database resource by rejecting any deletion request with the reason defined.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: protect-production-database
 6spec:
 7  of:
 8    apiVersion: rds.m.aws.m.upbound.io/v1beta1
 9    kind: Instance
10    resourceRef:
11      name: my-database
12  reason: "Production Database - should never be deleted!"

Usage for deletion ordering

The following example prevents the deletion of my-cluster resource by rejecting any deletion request before the deletion of my-prometheus-chart resource.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: release-uses-cluster
 6spec:
 7  of:
 8    apiVersion: eks.m.upbound.io/v1beta1
 9    kind: Cluster
10    resourceRef:
11      name: my-cluster
12  by:
13    apiVersion: helm.m.crossplane.io/v1beta1
14    kind: Release
15    resourceRef:
16      name: my-prometheus-chart

Using selectors with usages

Usages can use selectors to define the resource in use or the using one. This enables using labels or matching controller references to define resource instead of providing the resource name.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: release-uses-cluster
 6spec:
 7  of:
 8    apiVersion: eks.m.upbound.io/v1beta1
 9    kind: Cluster
10    resourceSelector:
11      matchControllerRef: false # default, and could be omitted
12      matchLabels:
13        foo: bar
14  by:
15    apiVersion: helm.m.crossplane.io/v1beta1
16    kind: Release
17    resourceSelector:
18       matchLabels:
19          baz: qux

After the Usage controller resolves the selectors, it persists the resource name in the resourceRef.name field. The following example shows the Usage resource after the resolution of selectors.

Important

The selectors are resolved only once. If there are more than one matches, a random resource is selected from the list of matched resources.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: release-uses-cluster
 6spec:
 7  of:
 8    apiVersion: eks.m.upbound.io/v1beta1
 9    kind: Cluster
10    resourceRef:
11       name: my-cluster
12    resourceSelector:
13      matchLabels:
14        foo: bar
15  by:
16    apiVersion: helm.m.crossplane.io/v1beta1
17    kind: Release
18    resourceRef:
19       name: my-cluster
20    resourceSelector:
21       matchLabels:
22          baz: qux

Replay blocked deletion attempt

By default, the deletion of a Usage resource doesn’t trigger the deletion of the resource in use even if there were deletion attempts blocked by the Usage. Replaying the blocked deletion is possible by setting the replayDeletion field to true.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: release-uses-cluster
 6spec:
 7  replayDeletion: true
 8  of:
 9    apiVersion: eks.m.upbound.io/v1beta1
10    kind: Cluster
11    resourceRef:
12      name: my-cluster
13  by:
14    apiVersion: helm.m.crossplane.io/v1beta1
15    kind: Release
16    resourceRef:
17      name: my-prometheus-chart
Tip
Replay deletion is useful when the used resource is part of a composition. This configuration radically decreases time for the deletion of the used resource, hence the composite owning it, by replaying the deletion of the used resource right after the using resource disappears instead of waiting for the long exponential backoff durations of the Kubernetes garbage collector.

Usage in a Composition

A typical use case for Usages is to define a deletion ordering between the resources in a Composition. The Usages support matching controller reference in selectors to ensures that the matching resource is in the same composite resource in the same way as cross-resource referencing.

Tip

When there are multiple resources of same type in a Composition, the Usage resource must uniquely identify the resource in use or the using one. This could be accomplished by using extra labels and combining matchControllerRef with a matchLabels selector.

Usage across namespaces

A Usage with of and by represents a usage relationship between two resources in the same namespace as the Usage by default.

A Usage can represent a usage relationship between a by resource in the same namespace as the Usage and an of resource in a different namespace.

To use a resource in a different namespace, specify the namespace in the of resourceRef or resourceSelector.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: Usage
 3metadata:
 4  namespace: default
 5  name: release-uses-cluster
 6spec:
 7  of:
 8    apiVersion: eks.m.upbound.io/v1beta1
 9    kind: Cluster
10    resourceRef:
11      namespace: cluster-infra
12      name: my-cluster
13  by:
14    apiVersion: helm.m.crossplane.io/v1beta1
15    kind: Release
16    resourceRef:
17      name: my-prometheus-chart

ClusterUsages

Use a ClusterUsage to protect cluster scoped resources.

 1apiVersion: protection.crossplane.io/v1beta1
 2kind: ClusterUsage
 3metadata:
 4  name: protect-important-crd
 5spec:
 6  of:
 7    apiVersion: apiextensions.k8s.io/v1
 8    kind: CustomResourceDefinition
 9    resourceRef:
10      name: importantresources.example.crossplane.io
11  reason: "Very important CRD - should never be deleted!"