docs/content/v1.18/concepts/composite-resources.md

15 KiB

title weight description
Composite Resources 50 Composite resources, an XR or XRs, represent a collection of related cloud resources.

A composite resource represents a set of managed resources as a single Kubernetes object. Crossplane creates composite resources when users access a custom API, defined in the CompositeResourceDefinition.

{{<hint "tip" >}} Composite resources are a composite of managed resources.
A Composition defines how to compose the managed resources together. {{< /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]({{<ref "./composite-resource-definitions">}}) (XRD) - A custom API specification.
  • Composite Resource (XR) - This page. 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. {{}}

Creating composite resources

Creating composite resources requires a [Composition]({{<ref "./compositions">}}) and a [CompositeResourceDefinition]({{<ref "./composite-resource-definitions">}}) (XRD).
The Composition defines the set of resources to create.
The XRD defines the custom API users call to request the set of resources.

Diagram of the relationship of Crossplane components

XRDs define the API used to create a composite resource.
For example, this {{}}CompositeResourceDefinition{{}} creates a custom API endpoint {{}}xmydatabases.example.org{{}}.

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata: 
  name: xmydatabases.example.org
spec:
  group: example.org
  names:
    kind: xMyDatabase
    plural: xmydatabases
  # Removed for brevity

When a user calls the custom API, {{}}xmydatabases.example.org{{}}, Crossplane chooses the Composition to use based on the Composition's {{}}compositeTypeRef{{}}

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: my-composition
spec:
  compositeTypeRef:
    apiVersion: example.org/v1alpha1
    kind: xMyDatabase
  # Removed for brevity

The Composition {{}}compositeTypeRef{{}} matches the XRD {{}}group{{}} and {{}}kind{{}}.

Crossplane creates the resources defined in the matching Composition and represents them as a single composite resource.

kubectl get composite
NAME                    SYNCED   READY   COMPOSITION         AGE
my-composite-resource   True     True    my-composition      4s

Naming external resources

By default, managed resources created by a composite resource have the name of the composite resource, followed by a random suffix.

For example, a composite resource named "my-composite-resource" creates external resources named "my-composite-resource-fqvkw."

Resource names can be deterministic by applying an {{}}annotation{{}} to the composite resource.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
  annotations: 
    crossplane.io/external-name: my-custom-name
# Removed for brevity

Inside the Composition, use a {{}}patch{{}} to apply the external-name to the resources.

The {{}}fromFieldPath{{}} patch copies the {{}}metadata.annotations{{}} field from the composite resource to the {{}}metadata.annotations{{}} inside the managed resource.

{{<hint "note" >}} If a managed resource has the crossplane.io/external-name annotation Crossplane uses the annotation value to name the external resource. {{}}

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: my-composition
spec:
  mode: Pipeline
  pipeline:
  - step: patch-and-transform
    functionRef:
      name: function-patch-and-transform
    input:
      apiVersion: pt.fn.crossplane.io/v1beta1
      kind: Resources
      resources:
      - name: database
        base:
          # Removed for brevity
        patches:
        - fromFieldPath: metadata.annotations
          toFieldPath: metadata.annotations

For more information on using function-patch-and-transform to patch resources refer to the [Function Patch and Transform]({{<ref "../guides/function-patch-and-transform">}}) documentation.

Composition selection

Select a specific Composition for a composite resource to use with {{}}compositionRef{{}}

{{<hint "important">}} The selected Composition must allow the composite resource to use it with a compositeTypeRef. Read more about the compositeTypeRef field in the [Enable Composite Resources]({{<ref "./compositions#enable-composite-resources">}}) section of the Composition documentation. {{< /hint >}}

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  compositionRef:
    name: my-other-composition
  # Removed for brevity

A composite resource can also select a Composition based on labels instead of the exact name with a {{}}compositionSelector{{}}.

Inside the {{}}matchLabels{{}} section provide one or more Composition labels to match.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  compositionSelector:
    matchLabels:
      environment: production
  # Removed for brevity

Composition revision policy

Crossplane tracks changes to Compositions as [Composition revisions]({{<ref "composition-revisions">}}) .

A composite resource can use a {{}}compositionUpdatePolicy{{}} to manually or automatically reference newer Composition revisions.

The default {{}}compositionUpdatePolicy{{}} is "Automatic." Composite resources automatically use the latest Composition revision.

Change the policy to {{}}Manual{{}} to prevent composite resources from automatically upgrading.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  compositionUpdatePolicy: Manual
  # Removed for brevity

Composition revision selection

Crossplane records changes to Compositions as [Composition revisions]({{<ref "composition-revisions">}}).
A composite resource can select a specific Composition revision.

Use {{}}compositionRevisionRef{{}} to select a specific Composition revision by name.

For example, to select a specific Composition revision use the name of the desired Composition revision.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  compositionUpdatePolicy: Manual
  compositionRevisionRef:
    name: my-composition-b5aa1eb
  # Removed for brevity

{{<hint "note" >}} Find the Composition revision name from {{}}kubectl get compositionrevision{{}}

kubectl get compositionrevision
NAME                         REVISION   XR-KIND        XR-APIVERSION            AGE
my-composition-5c976ad       1          xmydatabases   example.org/v1alpha1     65m
my-composition-b5aa1eb       2          xmydatabases   example.org/v1alpha1     64m

{{< /hint >}}

A Composite resource can also select Composition revisions based on labels instead of the exact name with a {{}}compositionRevisionSelector{{}}.

Inside the {{}}matchLabels{{}} section provide one or more Composition revision labels to match.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  compositionRevisionSelector:
    matchLabels:
      channel: dev
  # Removed for brevity

Manage connection secrets

When a composite resource creates resources, Crossplane provides any [connection secrets]({{<ref "./managed-resources#writeconnectionsecrettoref">}}) to the composite resource.

{{<hint "important" >}}

A resource may only access connection secrets allowed by the XRD. By default XRDs provide access to all connection secrets generated by managed resources.
Read more about [managing connection secrets]({{<ref "./composite-resource-definitions#manage-connection-secrets">}}) in the XRD documentation. {{< /hint >}}

Use {{}}writeConnectionSecretToRef{{}} to specify where the composite resource writes their connection secrets to.

For example, this composite resource saves the connection secrets in a Kubernetes secret object named {{}}my-secret{{}} in the namespace {{}}crossplane-system{{}}.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  writeConnectionSecretToRef:
    name: my-secret
    namespace: crossplane-system
  # Removed for brevity

Composite resources can write connection secrets to an [external secret store]({{<ref "../guides/vault-as-secret-store">}}), like HashiCorp Vault.

{{<hint "important" >}} External secret stores are an alpha feature. Alpha features aren't enabled by default. {{< /hint >}}

Use the {{}}publishConnectionDetailsTo{{}} field to save connection secrets to an external secrets store.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
spec:
  publishConnectionDetailsTo:
    name: my-external-secret-store
  # Removed for brevity

Read the [External Secrets Store]({{<ref "../guides/vault-as-secret-store">}}) documentation for more information on using external secret stores.

For more information on connection secrets read the [Connection Secrets knowledge base article]({{<ref "connection-details">}}).

Pausing composite resources

Crossplane supports pausing composite resources. A paused composite resource doesn't check or make changes on its external resources.

To pause a composite resource apply the {{}}crossplane.io/paused{{}} annotation.

apiVersion: example.org/v1alpha1
kind: xMyDatabase
metadata:
  name: my-composite-resource
  annotations:
    crossplane.io/paused: "true"
spec:
  # Removed for brevity

Verify composite resources

Use {{}}kubectl get composite{{}} to view all the composite resources Crossplane created.

kubectl get composite
NAME                    SYNCED   READY   COMPOSITION         AGE
my-composite-resource   True     True    my-composition      4s

Use kubectl get for the specific custom API endpoint to view only those resources.

kubectl get xMyDatabase.example.org
NAME                    SYNCED   READY   COMPOSITION        AGE
my-composite-resource   True     True    my-composition     12m

Use {{}}kubectl describe composite{{}} to view the linked {{}}Composition Ref{{}}, and unique managed resources created in the {{}}Resource Refs{{}}.

kubectl describe composite my-composite-resource
Name:         my-composite-resource
API Version:  example.org/v1alpha1
Kind:         xMyDatabase
Spec:
  Composition Ref:
    Name:  my-composition
  Composition Revision Ref:
    Name:                     my-composition-cf2d3a7
  Composition Update Policy:  Automatic
  Resource Refs:
    API Version:  s3.aws.upbound.io/v1beta1
    Kind:         Bucket
    Name:         my-composite-resource-fmrks
    API Version:  dynamodb.aws.upbound.io/v1beta1
    Kind:         Table
    Name:         my-composite-resource-wnr9t
# Removed for brevity

Composite resource conditions

The conditions of composite resources match the conditions of their managed resources.

Read the [conditions section]({{<ref "./managed-resources#conditions">}}) of the managed resources documentation for details.

Composite resource labels

Crossplane adds labels to composite resources to show their relationship to other Crossplane components.

Composite label

Crossplane adds the {{}} crossplane.io/composite{{}} label to all composite resources. The label matches the name of the composite. Crossplane applies the composite label to any managed resource created by a composite, creating a reference between the managed resource and owning composite resource.

kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
Name:         my-claimed-database2-x9rx9
Namespace:
Labels:       crossplane.io/composite=my-claimed-database-x9rx9

Claim name label

Crossplane adds the {{}}crossplane.io/claim-name{{}} label to composite resources created from a Claim. The label indicates the name of the Claim linked to this composite resource.

kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
Name:         my-claimed-database2-x9rx9
Namespace:
Labels:       crossplane.io/claim-name=my-claimed-database

Composite resources created directly, without using a Claim, don't have a {{}}crossplane.io/claim-name{{}} label.

Claim namespace label

Crossplane adds the {{}}crossplane.io/claim-namespace{{}} label to composite resources created from a Claim. The label indicates the namespace of the Claim linked to this composite resource.

kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
Name:         my-claimed-database2-x9rx9
Namespace:
Labels:       crossplane.io/claim-namespace=default

Composite resources created directly, without using a Claim, don't have a {{}}crossplane.io/claim-namespace{{}} label.