mirror of https://github.com/crossplane/docs.git
848 lines
28 KiB
Markdown
848 lines
28 KiB
Markdown
---
|
|
title: Composite Resource Definitions
|
|
weight: 40
|
|
description: "Composite Resource Definitions or XRDs define custom API schemas"
|
|
---
|
|
|
|
Composite resource definitions (`XRDs`) define the schema for a custom API.
|
|
Users create composite resources (`XRs`) and Claims (`XCs`) using the API
|
|
schema defined by an `XRD`.
|
|
|
|
|
|
{{< hint "note" >}}
|
|
|
|
Read the [composite resources]({{<ref "./composite-resources">}}) page for more
|
|
information about composite resources.
|
|
|
|
Read the [Claims]({{<ref "./claims">}}) page for more
|
|
information about Claims.
|
|
{{</hint >}}
|
|
|
|
|
|
{{<expand "Confused about Compositions, XRDs, XRs and Claims?" >}}
|
|
Crossplane has four core components that users commonly mix up:
|
|
|
|
* [Compositions]({{<ref "./compositions" >}}) - A template to define how to create resources.
|
|
* Composite Resource Definition (`XRD`) - This page. A custom API specification.
|
|
* [Composite Resource]({{<ref "./composite-resources">}}) (`XR`) - Created by
|
|
using the custom API defined in a Composite Resource Definition. XRs use the
|
|
Composition template to create new managed resources.
|
|
* [Claims]({{<ref "./claims" >}}) (`XRC`) - Like a Composite Resource, but
|
|
with namespace scoping.
|
|
{{</expand >}}
|
|
|
|
Crossplane XRDs are like
|
|
[Kubernetes custom resource definitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/).
|
|
XRDs require fewer fields and add options related to Crossplane, like Claims and
|
|
connection secrets.
|
|
|
|
## Creating a CompositeResourceDefinition
|
|
|
|
Creating a CompositeResourceDefinition consists of:
|
|
* [Defining a custom API group](#xrd-groups).
|
|
* [Defining a custom API name](#xrd-names).
|
|
* [Defining a custom API schema and version](#xrd-versions).
|
|
|
|
Optionally, CompositeResourceDefinitions also support:
|
|
* [Offering a Claim](#enable-claims).
|
|
* [Defining connection secrets](#manage-connection-secrets).
|
|
* [Setting composite resource defaults](#set-composite-resource-defaults).
|
|
|
|
Composite resource definitions (`XRDs`) create new API endpoints inside a
|
|
Kubernetes cluster.
|
|
|
|
Creating a new API requires defining an API
|
|
{{<hover label="xrd1" line="6">}}group{{</hover>}},
|
|
{{<hover label="xrd1" line="7">}}name{{</hover>}} and
|
|
{{<hover label="xrd1" line="10">}}version{{</hover>}}.
|
|
|
|
```yaml {label="xrd1",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xmydatabases.example.org
|
|
spec:
|
|
group: example.org
|
|
names:
|
|
kind: XMyDatabase
|
|
plural: xmydatabases
|
|
versions:
|
|
- name: v1alpha1
|
|
# Removed for brevity
|
|
```
|
|
|
|
After applying an XRD, Crossplane creates a new Kubernetes custom resource
|
|
definition matching the defined API.
|
|
|
|
For example, the XRD
|
|
{{<hover label="xrd1" line="4">}}xmydatabases.example.org{{</hover >}}
|
|
creates a custom resource definition
|
|
{{<hover label="kubeapi" line="2">}}xmydatabases.example.org{{</hover >}}.
|
|
|
|
```shell {label="kubeapi",copy-lines="3"}
|
|
kubectl api-resources
|
|
NAME SHORTNAMES APIVERSION NAMESPACED KIND
|
|
xmydatabases.example.org v1alpha1 false xmydatabases
|
|
# Removed for brevity
|
|
```
|
|
|
|
{{<hint "warning">}}
|
|
You can't change the XRD
|
|
{{<hover label="xrd1" line="6">}}group{{</hover>}} or
|
|
{{<hover label="xrd1" line="7">}}names{{</hover>}}.
|
|
You must delete and
|
|
recreate the XRD to change the
|
|
{{<hover label="xrd1" line="6">}}group{{</hover>}} or
|
|
{{<hover label="xrd1" line="7">}}names{{</hover>}}.
|
|
{{</hint >}}
|
|
|
|
### XRD groups
|
|
|
|
Groups define a collection of related API endpoints. The `group` can be any
|
|
value, but common convention is to map to a fully qualified domain name.
|
|
|
|
<!-- vale write-good.Weasel = NO -->
|
|
Many XRDs may use the same `group` to create a logical collection of APIs.
|
|
<!-- vale write-good.Weasel = YES -->
|
|
For example a `database` group may have a `relational` and `nosql` kinds.
|
|
|
|
{{<hint "tip" >}}
|
|
Group names are cluster scoped. Choose group names that don't conflict with
|
|
Providers.
|
|
Avoid Provider names in the group.
|
|
{{< /hint >}}
|
|
|
|
### XRD names
|
|
|
|
The `names` field defines how to refer to this specific XRD.
|
|
The required name fields are:
|
|
|
|
* `kind` - the `kind` value to use when calling this API. The kind is
|
|
[UpperCamelCased](https://kubernetes.io/docs/contribute/style/style-guide/#use-upper-camel-case-for-api-objects).
|
|
Crossplane recommends starting XRD `kinds` with an `X` to show
|
|
it's a custom Crossplane API definition.
|
|
* `plural` - the plural name used for the API URL. The plural name must be
|
|
lowercase.
|
|
|
|
{{<hint "important" >}}
|
|
The XRD
|
|
{{<hover label="xrdName" line="4">}}metadata.name{{</hover>}} must be
|
|
{{<hover label="xrdName" line="9">}}plural{{</hover>}} name, `.` (dot character),
|
|
{{<hover label="xrdName" line="6">}}group{{</hover>}}.
|
|
|
|
For example, {{<hover label="xrdName"
|
|
line="4">}}xmydatabases.example.org{{</hover>}} matches the {{<hover
|
|
label="xrdName" line="9">}}plural{{</hover>}} name
|
|
{{<hover label="xrdName" line="9">}}xmydatabases{{</hover>}}, `.`
|
|
{{<hover label="xrdName" line="6">}}group{{</hover>}} name,
|
|
{{<hover label="xrdName" line="6">}}example.org{{</hover>}}.
|
|
|
|
```yaml {label="xrdName",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xmydatabases.example.org
|
|
spec:
|
|
group: example.org
|
|
names:
|
|
kind: XMyDatabase
|
|
plural: xmydatabases
|
|
# Removed for brevity
|
|
```
|
|
{{</hint >}}
|
|
|
|
### XRD versions
|
|
|
|
<!-- vale gitlab.SentenceLength = NO -->
|
|
The XRD `version` is like the
|
|
[API versioning used by Kubernetes](https://kubernetes.io/docs/reference/using-api/#api-versioning).
|
|
The version shows how mature or stable the API is and increments when changing,
|
|
adding or removing fields in the API.
|
|
<!-- vale gitlab.SentenceLength = YES -->
|
|
|
|
Crossplane doesn't require specific versions or a specific version naming
|
|
convention, but following
|
|
[Kubernetes API versioning guidelines](https://kubernetes.io/docs/reference/using-api/#api-versioning)
|
|
is strongly recommended.
|
|
|
|
* `v1alpha1` - A new API that may change at any time.
|
|
* `v1beta1` - An existing API that's considered stable. Breaking changes are
|
|
strongly discouraged.
|
|
* `v1` - A stable API that doesn't have breaking changes.
|
|
|
|
#### Define a schema
|
|
|
|
<!-- vale write-good.Passive = NO -->
|
|
<!-- vale write-good.TooWordy = NO -->
|
|
The `schema` defines the names
|
|
of the parameters, the data types of the parameters and which parameters are
|
|
required or optional.
|
|
<!-- vale write-good.Passive = YES -->
|
|
<!-- vale write-good.TooWordy = YES -->
|
|
|
|
{{<hint "note" >}}
|
|
All `schemas` follow the Kubernetes custom resource definition
|
|
[OpenAPIv3 structural schema](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
|
|
{{< /hint >}}
|
|
|
|
Each
|
|
{{<hover label="schema" line="11">}}version{{</hover>}} of the API has a unique
|
|
{{<hover label="schema" line="12">}}schema{{</hover>}}.
|
|
|
|
All XRD {{<hover label="schema" line="12">}}schemas{{</hover>}} validate against
|
|
the {{<hover label="schema" line="13">}}openAPIV3Schema{{</hover>}}. The schema
|
|
is an OpenAPI
|
|
{{<hover label="schema" line="14">}}object{{</hover>}} with the
|
|
{{<hover label="schema" line="15">}}properties{{</hover>}} of a
|
|
{{<hover label="schema" line="16">}}spec{{</hover>}}
|
|
{{<hover label="schema" line="17">}}object{{</hover>}}.
|
|
|
|
Inside the {{<hover label="schema" line="18">}}spec.properties{{</hover>}} is the custom
|
|
API definition.
|
|
|
|
In this example, the key {{<hover label="schema" line="19">}}region{{</hover>}}
|
|
is a {{<hover label="schema" line="20">}}string{{</hover>}}.
|
|
|
|
```yaml {label="schema",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
versions:
|
|
- name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
# Removed for brevity
|
|
```
|
|
|
|
A composite resource using this API references the
|
|
{{<hover label="xr" line="1">}}group/version{{</hover>}} and
|
|
{{<hover label="xr" line="2">}}kind{{</hover>}}. The
|
|
{{<hover label="xr" line="5">}}spec{{</hover>}} has the
|
|
{{<hover label="xr" line="6">}}region{{</hover>}} key with a string value.
|
|
|
|
```yaml {label="xr"}
|
|
apiVersion: custom-api.example.org/v1alpha1
|
|
kind: xDatabase
|
|
metadata:
|
|
name: my-composite-resource
|
|
spec:
|
|
region: "US"
|
|
```
|
|
|
|
|
|
{{<hint "tip" >}}
|
|
The custom API defined inside the
|
|
{{<hover label="schema" line="18">}}spec.properties{{</hover>}} is an OpenAPIv3
|
|
specification. The
|
|
[data models page](https://swagger.io/docs/specification/data-models/) of
|
|
the Swagger documentation provides a list of examples using data types and input
|
|
restrictions.
|
|
|
|
The Kubernetes documentation lists
|
|
[the set of special restrictions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation)
|
|
on what your OpenAPIv3 custom API can use.
|
|
{{< /hint >}}
|
|
|
|
{{<hint "important" >}}
|
|
|
|
Changing or expanding the XRD schema requires restarting the [Crossplane pod]({{<ref "./pods#crossplane-pod">}}) to take effect.
|
|
{{< /hint >}}
|
|
|
|
##### Required fields
|
|
|
|
By default all fields in a schema are optional. Define a parameter as required
|
|
with the
|
|
{{< hover label="required" line="25">}}required{{</hover>}} attribute.
|
|
|
|
In this example the XRD requires
|
|
{{< hover label="required" line="19">}}region{{</hover>}} and
|
|
{{< hover label="required" line="21">}}size{{</hover>}} but
|
|
{{< hover label="required" line="23">}}name{{</hover>}} is optional.
|
|
```yaml {label="required",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
versions:
|
|
- name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
size:
|
|
type: string
|
|
name:
|
|
type: string
|
|
required:
|
|
- region
|
|
- size
|
|
# Removed for brevity
|
|
```
|
|
|
|
According to the OpenAPIv3 specification, the `required` field is per-object. If
|
|
a schema contains multiple objects the schema may need multiple `required`
|
|
fields.
|
|
|
|
This XRD defines two objects:
|
|
1. the top-level {{<hover label="required2" line="7">}}spec{{</hover>}} object
|
|
2. a second {{<hover label="required2" line="14">}}location{{</hover>}} object
|
|
|
|
The {{<hover label="required2" line="7">}}spec{{</hover>}} object
|
|
{{<hover label="required2" line="23">}}requires{{</hover>}} the
|
|
{{<hover label="required2" line="10">}}size{{</hover>}} and
|
|
{{<hover label="required2" line="14">}}location{{</hover>}} but
|
|
{{<hover label="required2" line="12">}}name{{</hover>}} is optional.
|
|
|
|
Inside the required {{<hover label="required2" line="14">}}location{{</hover>}}
|
|
object,
|
|
{{<hover label="required2" line="17">}}country{{</hover>}} is
|
|
{{<hover label="required2" line="21">}}required{{</hover>}} and
|
|
{{<hover label="required2" line="19">}}zone{{</hover>}} is optional.
|
|
|
|
```yaml {copy-lines="none",label="required2"}
|
|
# Removed for brevity
|
|
- name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
size:
|
|
type: string
|
|
name:
|
|
type: string
|
|
location:
|
|
type: object
|
|
properties:
|
|
country:
|
|
type: string
|
|
zone:
|
|
type: string
|
|
required:
|
|
- country
|
|
required:
|
|
- size
|
|
- location
|
|
```
|
|
|
|
The Swagger "[Describing Parameters](https://swagger.io/docs/specification/describing-parameters/)"
|
|
documentation has more examples.
|
|
|
|
##### Crossplane reserved fields
|
|
|
|
Crossplane doesn't allow the following fields in a schema:
|
|
* `spec.resourceRef`
|
|
* `spec.resourceRefs`
|
|
* `spec.claimRef`
|
|
* `spec.writeConnectionSecretToRef`
|
|
* `status.conditions`
|
|
* `status.connectionDetails`
|
|
|
|
Crossplane ignores any fields matching the reserved fields.
|
|
|
|
#### Serve and reference a schema
|
|
|
|
To use a schema it must be
|
|
{{<hover label="served" line="12" >}}served: true{{</hover >}}
|
|
and
|
|
{{<hover label="served" line="13" >}}referenceable: true{{</hover>}}.
|
|
|
|
```yaml {label="served"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
versions:
|
|
- name: v1alpha1
|
|
served: true
|
|
referenceable: true
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
```
|
|
|
|
Composite resources can use any schema version set as
|
|
{{<hover label="served" line="12" >}}served: true{{</hover >}}.
|
|
Kubernetes rejects any composite resource using a schema version set as `served:
|
|
false`.
|
|
|
|
{{< hint "tip" >}}
|
|
Setting a schema version as `served:false` causes errors for users using an older
|
|
schema. This can be an effective way to identify and upgrade users before
|
|
deleting the older schema version.
|
|
{{< /hint >}}
|
|
|
|
The {{<hover label="served" line="13" >}}referenceable: true{{</hover>}}
|
|
field indicates which version of the schema Compositions use. Only one
|
|
version can be `referenceable`.
|
|
|
|
{{< hint "note" >}}
|
|
Changing which version is `referenceable:true` requires [updating the `compositeTypeRef.apiVersion`]({{<ref "./compositions#enable-composite-resources" >}})
|
|
of any Compositions referencing that XRD.
|
|
{{< /hint >}}
|
|
|
|
|
|
#### Multiple schema versions
|
|
|
|
{{<hint "warning" >}}
|
|
Crossplane supports defining multiple `versions`, but the schema of each version
|
|
can't change any existing fields, also called "making a breaking change."
|
|
|
|
Breaking schema changes between versions requires the use of [conversion webhooks](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion).
|
|
|
|
New versions may define new optional parameters, but new required fields are
|
|
a "breaking change."
|
|
|
|
<!-- vale Crossplane.Spelling = NO -->
|
|
<!-- ignore to allow for CRDs -->
|
|
<!-- don't add to the spelling exceptions to catch when it's used instead of XRD -->
|
|
Crossplane XRDs use Kubernetes custom resource definitions for versioning.
|
|
Read the Kubernetes documentation on
|
|
[versions in CustomResourceDefinitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/)
|
|
for more background on versions and breaking changes.
|
|
<!-- vale Crossplane.Spelling = YES -->
|
|
|
|
Crossplane recommends implementing breaking schema changes as brand new XRDs.
|
|
{{< /hint >}}
|
|
|
|
For XRDs, to create a new version of an API add a new
|
|
{{<hover label="ver" line="21">}}name{{</hover>}} in the
|
|
{{<hover label="ver" line="10">}}versions{{</hover>}}
|
|
list.
|
|
|
|
For example, this XRD version
|
|
{{<hover label="ver" line="11">}}v1alpha1{{</hover>}} only has the field
|
|
{{<hover label="ver" line="19">}}region{{</hover>}}.
|
|
|
|
A second version,
|
|
{{<hover label="ver" line="21">}}v1{{</hover>}} expands the API to have both
|
|
{{<hover label="ver" line="29">}}region{{</hover>}} and
|
|
{{<hover label="ver" line="31">}}size{{</hover>}}.
|
|
|
|
```yaml {label="ver",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
versions:
|
|
- name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
- name: v1
|
|
schema:
|
|
openAPIV3Schema:
|
|
type: object
|
|
properties:
|
|
spec:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
size:
|
|
type: string
|
|
```
|
|
|
|
{{<hint "important" >}}
|
|
|
|
Changing or expanding the XRD schema requires restarting the [Crossplane pod]({{<ref "./pods#crossplane-pod">}}) to take effect.
|
|
{{< /hint >}}
|
|
|
|
### Enable Claims
|
|
|
|
Optionally, XRDs can allow Claims to use the XRD API.
|
|
|
|
{{<hint "note" >}}
|
|
|
|
Read the [Claims]({{<ref "./claims">}}) page for more
|
|
information about Claims.
|
|
{{</hint >}}
|
|
|
|
XRDs offer Claims with a
|
|
{{<hover label="claim" line="10">}}claimNames{{</hover >}} object.
|
|
|
|
The {{<hover label="claim" line="10">}}claimNames{{</hover >}} defines a
|
|
{{<hover label="claim" line="11">}}kind{{</hover >}} and
|
|
{{<hover label="claim" line="12">}}plural{{</hover >}} like the XRD
|
|
{{<hover label="claim" line="7">}}names{{</hover >}} object.
|
|
Also like XRD
|
|
{{<hover label="claim" line="7">}}names{{</hover >}}, use UpperCamelCase
|
|
for the
|
|
{{<hover label="claim" line="11">}}kind{{</hover >}} and lowercase for the
|
|
{{<hover label="claim" line="12">}}plural{{</hover >}}.
|
|
|
|
The Claim
|
|
{{<hover label="claim" line="11">}}kind{{</hover >}} and
|
|
{{<hover label="claim" line="12">}}plural{{</hover >}} must be unique. They
|
|
can't match any other Claim or other XRD
|
|
{{<hover label="claim" line="8">}}kind{{</hover >}}.
|
|
|
|
{{<hint "tip" >}}
|
|
Common Crossplane convention is to use
|
|
{{<hover label="claim" line="10">}}claimNames{{</hover >}} that match the XRD
|
|
{{<hover label="claim" line="7">}}names{{</hover >}}, but without the beginning
|
|
"x."
|
|
{{</hint >}}
|
|
|
|
```yaml {label="claim",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
claimNames:
|
|
kind: Database
|
|
plural: databases
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
{{<hint "important" >}}
|
|
You can't change the
|
|
{{<hover label="claim" line="10">}}claimNames{{</hover >}}
|
|
after they're defined. You must delete and
|
|
recreate the XRD to change the
|
|
{{<hover label="claim" line="10">}}claimNames{{</hover >}}.
|
|
{{</hint >}}
|
|
|
|
### Manage connection secrets
|
|
|
|
When a composite resource creates managed resources, Crossplane provides any
|
|
[connection secrets]({{<ref "./managed-resources#writeconnectionsecrettoref">}})
|
|
to the composite resource or Claim. This requires the creators of composite
|
|
resources and Claims to know the secrets provided by a managed resource.
|
|
In other cases, Crossplane administrators may not want to expose some or all the
|
|
generated connection secrets.
|
|
|
|
XRDs can define a list of
|
|
{{<hover label="key" line="10">}}connectionSecretKeys{{</hover>}}
|
|
to limit what's provided to a composite resource or Claim.
|
|
|
|
Crossplane only provides the keys listed in the
|
|
{{<hover label="key" line="10">}}connectionSecretKeys{{</hover>}}
|
|
to the composite resource or Claim using this XRD. Any other connection
|
|
secrets aren't passed to the composite resource or Claim.
|
|
|
|
{{<hint "important" >}}
|
|
The keys listed in the
|
|
{{<hover label="key" line="10">}}connectionSecretKeys{{</hover>}} must match the
|
|
key names listed in the Composition's `connectionDetails`.
|
|
|
|
An XRD ignores any keys listed that aren't created by a managed resource.
|
|
|
|
For more information read the
|
|
[Composition documentation]({{<ref "./compositions#store-connection-details">}}).
|
|
{{< /hint >}}
|
|
|
|
|
|
For example, an XRD passes the keys
|
|
{{<hover label="key" line="11">}}username{{</hover>}},
|
|
{{<hover label="key" line="12">}}password{{</hover>}} and
|
|
{{<hover label="key" line="13">}}address{{</hover>}}.
|
|
|
|
Composite resources or Claims save these in the secret defined by their
|
|
`writeConnectionSecretToRef` field.
|
|
|
|
```yaml {label="key",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
group: custom-api.example.org
|
|
names:
|
|
kind: xDatabase
|
|
plural: xdatabases
|
|
connectionSecretKeys:
|
|
- username
|
|
- password
|
|
- address
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
{{<hint "warning">}}
|
|
You can't change the `connectionSecretKeys` of an XRD. You must delete and
|
|
recreate the XRD to change the `connectionSecretKeys`.
|
|
{{</hint >}}
|
|
|
|
For more information on connection secrets read the
|
|
[Connection Secrets knowledge base article]({{<ref "connection-details">}}).
|
|
|
|
### Set composite resource defaults
|
|
XRDs can set default parameters for composite resources and Claims.
|
|
|
|
<!-- vale off -->
|
|
#### defaultCompositeDeletePolicy
|
|
<!-- vale on -->
|
|
The `defaultCompositeDeletePolicy` defines the default value for the claim's
|
|
`compositeDeletePolicy` property if the user doesn't specify a value when creating
|
|
the claim. The claim controller uses the `compositeDeletePolicy` property to specify
|
|
the propagation policy when deleting the associated composite.
|
|
The `compositeDeletePolicy` doesn't apply to standalone composites that don't have
|
|
associated claims.
|
|
|
|
Using a `defaultCompositeDeletePolicy: Background` policy causes the CRD for the claim to have
|
|
the default value `Background` for the `compositeDeletePolicy` property.
|
|
When a deleted claim has the `compositeDeletePolicy` property set to `Background`
|
|
the claim controller deletes the composite resource using the propagation policy `background`
|
|
and returns, relying on Kubernetes to delete the remaining child objects,
|
|
like managed resources, nested composites and secrets.
|
|
|
|
Using `defaultCompositeDeletePolicy: Foreground` causes the CRD for the claim to have
|
|
the `compositeDeletePolicy` default value `Foreground`. When a deleted claim has the
|
|
`compositeDeletePolicy` property set to `Foreground` the controller
|
|
deletes the associated composite using the propagation policy `foreground`. This causes Kubernetes
|
|
to use foreground cascading deletion which deletes all child resources before deleting the
|
|
parent resource. The claim controller waits for the composite deletion to finish before returning.
|
|
|
|
When creating a claim the user can override the `defaultCompositeDeletePolicy` by including
|
|
the `spec.compositeDeletePolicy` property with either the `Background` or `Foreground` value.
|
|
|
|
The default value is `defaultCompositeDeletePolicy: Background`.
|
|
|
|
Set
|
|
{{<hover label="delete" line="6">}}defaultCompositeDeletePolicy: Foreground{{</hover>}}
|
|
to change the XRD deletion policy.
|
|
|
|
```yaml {label="delete",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
defaultCompositeDeletePolicy: Foreground
|
|
group: custom-api.example.org
|
|
names:
|
|
# Removed for brevity
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### defaultCompositionRef
|
|
<!-- vale on -->
|
|
It's possible for multiple [Compositions]({{<ref "./compositions">}}) to
|
|
reference the same XRD. If more than one Composition references the same XRD,
|
|
the composite resource or Claim must select which Composition to use.
|
|
|
|
An XRD can define the default Composition to use with the
|
|
`defaultCompositionRef` value.
|
|
|
|
Set a
|
|
{{<hover label="defaultComp" line="6">}}defaultCompositionRef{{</hover>}}
|
|
to set the default Composition.
|
|
|
|
```yaml {label="defaultComp",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
defaultCompositionRef:
|
|
name: myComposition
|
|
group: custom-api.example.org
|
|
names:
|
|
# Removed for brevity
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### defaultCompositionUpdatePolicy
|
|
<!-- vale on -->
|
|
|
|
Changes to a Composition generate a new Composition revision. By default all
|
|
composite resources and Claims use the updated Composition revision.
|
|
|
|
Set the XRD `defaultCompositionUpdatePolicy` to `Manual` to prevent composite
|
|
resources and Claims from automatically using the new revision.
|
|
|
|
The default value is `defaultCompositionUpdatePolicy: Automatic`.
|
|
|
|
Set {{<hover label="compRev" line="6">}}defaultCompositionUpdatePolicy: Manual{{</hover>}}
|
|
to set the default Composition update policy for composite resources and Claims
|
|
using this XRD.
|
|
|
|
```yaml {label="compRev",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
defaultCompositionUpdatePolicy: Manual
|
|
group: custom-api.example.org
|
|
names:
|
|
# Removed for brevity
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### enforcedCompositionRef
|
|
<!-- vale on -->
|
|
To require all composite resources or Claims to use a specific Composition use
|
|
the `enforcedCompositionRef` setting in the XRD.
|
|
|
|
For example, to require all composite resources and Claims using this XRD to use
|
|
the Composition
|
|
{{<hover label="enforceComp" line="6">}}myComposition{{</hover>}}
|
|
set
|
|
{{<hover label="enforceComp" line="6">}}enforcedCompositionRef.name: myComposition{{</hover>}}.
|
|
|
|
```yaml {label="defaultComp",copy-lines="none"}
|
|
apiVersion: apiextensions.crossplane.io/v1
|
|
kind: CompositeResourceDefinition
|
|
metadata:
|
|
name: xdatabases.custom-api.example.org
|
|
spec:
|
|
enforcedCompositionRef:
|
|
name: myComposition
|
|
group: custom-api.example.org
|
|
names:
|
|
# Removed for brevity
|
|
versions:
|
|
# Removed for brevity
|
|
```
|
|
|
|
## Verify a CompositeResourceDefinition
|
|
|
|
Verify an XRD with `kubectl get compositeresourcedefinition` or the short form,
|
|
{{<hover label="getxrd" line="1">}}kubectl get xrd{{</hover>}}.
|
|
|
|
```yaml {label="getxrd",copy-lines="1"}
|
|
kubectl get xrd
|
|
NAME ESTABLISHED OFFERED AGE
|
|
xdatabases.custom-api.example.org True True 22m
|
|
```
|
|
|
|
The `ESTABLISHED` field indicates Crossplane installed the Kubernetes custom
|
|
resource definition for this XRD.
|
|
|
|
The `OFFERED` field indicates this XRD offers a Claim and Crossplane installed
|
|
the Kubernetes custom resource definitions for the Claim.
|
|
|
|
### XRD conditions
|
|
Crossplane uses a standard set of `Conditions` for XRDs.
|
|
View the conditions of a XRD under their `Status` with
|
|
`kubectl describe xrd`.
|
|
|
|
```yaml {copy-lines="none"}
|
|
kubectl describe xrd
|
|
Name: xpostgresqlinstances.database.starter.org
|
|
API Version: apiextensions.crossplane.io/v1
|
|
Kind: CompositeResourceDefinition
|
|
# Removed for brevity
|
|
Status:
|
|
Conditions:
|
|
Reason: WatchingCompositeResource
|
|
Status: True
|
|
Type: Established
|
|
Reason: WatchingCompositeResourceClaim
|
|
Status: True
|
|
Type: Offered
|
|
# Removed for brevity
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### WatchingCompositeResource
|
|
<!-- vale on -->
|
|
`Reason: WatchingCompositeResource` indicates Crossplane defined the new
|
|
Kubernetes custom resource definitions related to the composite resource and is
|
|
watching for the creation of new composite resources.
|
|
|
|
```yaml
|
|
Type: Established
|
|
Status: True
|
|
Reason: WatchingCompositeResource
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### TerminatingCompositeResource
|
|
<!-- vale on -->
|
|
`Reason: TerminatingCompositeResource` indicates Crossplane is deleting the
|
|
custom resource definitions related to the composite resource and is
|
|
terminating the composite resource controller.
|
|
|
|
```yaml
|
|
Type: Established
|
|
Status: False
|
|
Reason: TerminatingCompositeResource
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### WatchingCompositeResourceClaim
|
|
<!-- vale on -->
|
|
`Reason: WatchingCompositeResourceClaim` indicates Crossplane defined the new
|
|
Kubernetes custom resource definitions related to the offered Claims and is
|
|
watching for the creation of new Claims.
|
|
|
|
```yaml
|
|
Type: Offered
|
|
Status: True
|
|
Reason: WatchingCompositeResourceClaim
|
|
```
|
|
|
|
<!-- vale off -->
|
|
#### TerminatingCompositeResourceClaim
|
|
<!-- vale on -->
|
|
`Reason: TerminatingCompositeResourceClaim` indicates Crossplane is deleting the
|
|
custom resource definitions related to the offered Claims and is
|
|
terminating the Claims controller.
|
|
|
|
```yaml
|
|
Type: Offered
|
|
Status: False
|
|
Reason: TerminatingCompositeResourceClaim
|
|
``` |