--- title: Usages weight: 30 state: beta alphaVersion: "1.14" betaVersion: "1.19" description: "Block deletion of in-use resources" --- 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](#usage-for-deletion-protection) for the first use case and the section [Usage for Deletion Ordering](#usage-for-deletion-ordering) for the second one. ## Enable usages Usages are a beta feature. Crossplane enables beta features by default. Disable `Usage` support by [changing the Crossplane pod setting]({{}}) and setting {{}}--enable-usages=false{{}} argument. ```yaml {label="deployment",copy-lines="12"} $ kubectl edit deployment crossplane --namespace crossplane-system apiVersion: apps/v1 kind: Deployment spec: # Removed for brevity template: spec: containers: - args: - core - start - --enable-usages=false ``` {{}} The [Crossplane install guide]({{}}) describes enabling feature flags like {{}}\-\-enable-usages{{}} with Helm. {{< /hint >}} ## 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. ```yaml {label="protect"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: protect-production-database spec: of: apiVersion: rds.aws.m.upbound.io/v1beta1 kind: Instance resourceRef: name: my-database 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. ```yaml {label="order"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: release-uses-cluster spec: of: apiVersion: eks.m.upbound.io/v1beta1 kind: Cluster resourceRef: name: my-cluster by: apiVersion: helm.m.crossplane.io/v1beta1 kind: Release resourceRef: 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. ```yaml {label="selectors"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: release-uses-cluster spec: of: apiVersion: eks.m.upbound.io/v1beta1 kind: Cluster resourceSelector: matchControllerRef: false # default, and could be omitted matchLabels: foo: bar by: apiVersion: helm.m.crossplane.io/v1beta1 kind: Release resourceSelector: matchLabels: 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. {{}} The selectors are resolved only once. If there are more than one matches, a random resource is selected from the list of matched resources. {{< /hint >}} ```yaml {label="selectors-resolved"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: release-uses-cluster spec: of: apiVersion: eks.m.upbound.io/v1beta1 kind: Cluster resourceRef: name: my-cluster resourceSelector: matchLabels: foo: bar by: apiVersion: helm.m.crossplane.io/v1beta1 kind: Release resourceRef: name: my-cluster resourceSelector: matchLabels: 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`. ```yaml {label="replay"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: release-uses-cluster spec: replayDeletion: true of: apiVersion: eks.m.upbound.io/v1beta1 kind: Cluster resourceRef: name: my-cluster by: apiVersion: helm.m.crossplane.io/v1beta1 kind: Release resourceRef: name: my-prometheus-chart ``` {{}} 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. {{< /hint >}} ## 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]({{}}). {{}} 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. {{< /hint >}} ## 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`. ```yaml {label="order"} apiVersion: protection.crossplane.io/v1beta1 kind: Usage metadata: namespace: default name: release-uses-cluster spec: of: apiVersion: eks.m.upbound.io/v1beta1 kind: Cluster resourceRef: namespace: cluster-infra name: my-cluster by: apiVersion: helm.m.crossplane.io/v1beta1 kind: Release resourceRef: name: my-prometheus-chart ``` ## ClusterUsages Use a `ClusterUsage` to protect cluster scoped resources. ```yaml {label="protect"} apiVersion: protection.crossplane.io/v1beta1 kind: ClusterUsage metadata: name: protect-important-crd spec: of: apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition resourceRef: name: importantresources.example.crossplane.io reason: "Very important CRD - should never be deleted!" ```