Azure Quickstart Part 2

This document is for an older version of Crossplane.

This document applies to Crossplane version v1.11 and not to the latest release v1.13.

Important

This guide is part 2 of a series. Follow part 1 to install Crossplane and connect your Kubernetes cluster to Azure.

Part 3 covers patching CompositeResources and using Crossplane Packages.

This section creates a Composition, CompositeResourceDefinition and a Claim to create a custom Kubernetes API to create Azure resources. This custom API is a composite resource (XR) API.

Prerequisites

  • Complete quickstart part 1 connecting Kubernetes to Azure.
  • an Azure account with permissions to create an Azure Virtual Machine and Virtual Networking

  1. Add the Crossplane Helm repository and install Crossplane
1helm repo add \
2crossplane-stable https://charts.crossplane.io/stable
3helm repo update
4&&
5helm install crossplane \
6crossplane-stable/crossplane \
7--namespace crossplane-system \
8--create-namespace
  1. When the Crossplane pods finish installing and are ready, apply the Azure Provider
1cat <<EOF | kubectl apply -f -
2apiVersion: pkg.crossplane.io/v1
3kind: Provider
4metadata:
5  name: upbound-provider-azure
6spec:
7  package: xpkg.upbound.io/upbound/provider-azure:v0.32.0
8EOF
  1. Use the Azure CLI to create a service principal and save the JSON output as azure-crednetials.json
1az ad sp create-for-rbac \
2--sdk-auth \
3--role Owner \
4--scopes /subscriptions/$$<subscription_id>$$
  1. Create a Kubernetes secret from the Azure JSON file.
1kubectl create secret \
2generic azure-secret \
3-n crossplane-system \
4--from-file=creds=./azure-credentials.json
  1. Create a ProviderConfig
 1cat <<EOF | kubectl apply -f -
 2apiVersion: azure.upbound.io/v1beta1
 3metadata:
 4  name: default
 5kind: ProviderConfig
 6spec:
 7  credentials:
 8    source: Secret
 9    secretRef:
10      namespace: crossplane-system
11      name: azure-secret
12      key: creds
13EOF

Create a composition

Part 1 created a single managed resource. A Composition is a template to create one or more managed resource at the same time.

This sample composition creates an Linux Virtual Machine and the required networking components.

Compositions have multiple components:

  • The individual managed resources.
  • The Composition kind and version.
  • A Composite type reference.

The following steps describe each of these components before applying the final Composition.

Define a virtual network

Define a virtualnetwork resource using the configuration from the previous section:

Note
Don’t apply this configuration. This YAML is part of a larger definition.
 1apiVersion: network.azure.upbound.io/v1beta1
 2kind: VirtualNetwork
 3metadata:
 4  name: crossplane-quickstart-network
 5spec:
 6  forProvider:
 7    addressSpace:
 8      - 10.0.0.0/16
 9    location: "Central US"
10    resourceGroupName: <resource_group_name>

Define a subnet resource

Next, define a Subnet resource.

Note
Don’t apply this configuration. This YAML is part of a larger definition.
1apiVersion: network.azure.upbound.io/v1beta1
2kind: Subnet
3metadata:
4  name: crossplane-quickstart-subnet
5spec:
6  forProvider:
7    addressPrefixes:
8      - 10.0.1.0/24
9    resourceGroupName: <resource_group_name>

Define a network interface

Define a network interface to attach to the virtual machine.

Note
Don’t apply this configuration. This YAML is part of a larger definition.
 1apiVersion: network.azure.upbound.io/v1beta1
 2kind: NetworkInterface
 3metadata:
 4  name: crossplane-quickstart-nic
 5spec:
 6  forProvider:
 7    ipConfiguration:
 8      - name: crossplane-quickstart-configuration
 9        privateIpAddressAllocation: Dynamic
10    location: "Central US"
11    resourceGroupName: <resource_group_name>

Define a virtual machine

Define the LinuxVirtualMachine with its settings.

Note
Don’t apply this configuration. This YAML is part of a larger definition.
 1apiVersion: compute.azure.upbound.io/v1beta1
 2kind: LinuxVirtualMachine
 3metadata:
 4  name: crossplane-quickstart-vm
 5spec:
 6  forProvider:
 7    adminUsername: adminuser
 8    adminSshKey:
 9      - publicKey: ssh-rsa
10          AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
11          example@docs.crossplane.io
12        username: adminuser
13    location: "Central US"
14    osDisk:
15      - caching: ReadWrite
16        storageAccountType: Standard_LRS
17    size: Standard_B1ms	
18    sourceImageReference:
19      - offer: debian-11
20        publisher: Debian
21        sku: 11-backports-gen2
22        version: latest
23    resourceGroupName: <resource_group_name>

Create the composition object

The Composition combines all the managed resources into a single object.

A Composition comes from the Crossplane API resources.

Create any name for this Composition.

1apiVersion: apiextensions.crossplane.io/v1
2kind: Composition
3metadata:
4  name: crossplane-quickstart-vm-with-network

Add all the defined resources to the spec.resources section of the Composition.

Give each resource a name and put the resource definition under the base key.

Add your resourceGroupName for each resource in the Composition.

Important
The contents of the base key doesn’t include the metadata field from the managed resources.
 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: crossplane-quickstart-vm-with-network
 5spec:
 6  resources:
 7    - name: quickstart-subnet
 8      base:
 9        apiVersion: network.azure.upbound.io/v1beta1
10        kind: Subnet
11        spec:
12          forProvider:
13            addressPrefixes:
14              - 10.0.1.0/24
15            virtualNetworkNameSelector:
16              matchControllerRef: true
17            resourceGroupName: <resource_group_name>
18# Removed for brevity
Tip
Crossplane provides the matchControllerRef value to automatically link resources created by the same Composition.

Compositions are a template for generating resources. A composite resource actually creates the resources.

A Composition defines what composite resources can use this template.

Compositions do this with the spec.compositeTypeRef definition.

Tip
Crossplane recommends prefacing the kind with an X to show it’s a Composition.
 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: crossplane-quickstart-vm-with-network
 5spec:
 6  compositeTypeRef:
 7    apiVersion: custom-api.example.org/v1alpha1
 8    kind: XVirtualMachine
 9  resources:
10    # Removed for Brevity    

A composite resource is actually a custom Kubernetes API type you define. The platform team controls the kind, API endpoint and version.

With this spec.compositeTypeRef Crossplane only allows composite resources from the API group custom-api.example.org that are of kind: XVirtualMachine to use this template to create resources.

Apply the composition

Apply the full Composition to your Kubernetes cluster.

Important
Add your resourceGroupName to each resource.
 1cat <<EOF | kubectl apply -f -
 2apiVersion: apiextensions.crossplane.io/v1
 3kind: Composition
 4metadata:
 5  name: crossplane-quickstart-vm-with-network
 6spec:
 7  compositeTypeRef:
 8    apiVersion: custom-api.example.org/v1alpha1
 9    kind: XVirtualMachine
10  resources:
11    - name: quickstart-vm
12      base:
13        apiVersion: compute.azure.upbound.io/v1beta1
14        kind: LinuxVirtualMachine
15        spec:
16          forProvider:
17            adminUsername: adminuser
18            adminSshKey:
19              - publicKey: ssh-rsa
20                  AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
21                  example@docs.crossplane.io
22                username: adminuser
23            location: "Central US"
24            osDisk:
25              - caching: ReadWrite
26                storageAccountType: Standard_LRS
27            resourceGroupName: $$<resource_group_name>$$
28            size: Standard_B1ms
29            sourceImageReference:
30              - offer: debian-11
31                publisher: Debian
32                sku: 11-backports-gen2
33                version: latest
34            networkInterfaceIdsSelector:
35              matchControllerRef: true
36    - name: quickstart-nic
37      base:
38        apiVersion: network.azure.upbound.io/v1beta1
39        kind: NetworkInterface
40        spec:
41          forProvider:
42            ipConfiguration:
43              - name: crossplane-quickstart-configuration
44                privateIpAddressAllocation: Dynamic
45                subnetIdSelector:
46                  matchControllerRef: true
47            location: "Central US"
48            resourceGroupName: $$<resource_group_name>$$
49    - name: quickstart-subnet
50      base:
51        apiVersion: network.azure.upbound.io/v1beta1
52        kind: Subnet
53        spec:
54          forProvider:
55            addressPrefixes:
56              - 10.0.1.0/24
57            virtualNetworkNameSelector:
58              matchControllerRef: true
59            resourceGroupName: $$<resource_group_name>$$
60    - name: quickstart-network
61      base:
62        apiVersion: network.azure.upbound.io/v1beta1
63        kind: VirtualNetwork
64        spec:
65          forProvider:
66            addressSpace:
67              - 10.0.0.0/16
68            location: "Central US"
69            resourceGroupName: $$<resource_group_name>$$
70EOF

Confirm the Composition exists with kubectl get composition

1kubectl get composition
2NAME                                    XR-KIND           XR-APIVERSION                     AGE
3crossplane-quickstart-vm-with-network   XVirtualMachine   custom-api.example.org/v1alpha1   5s

Again, the Composition is only a template. At this point, Crossplane hasn’t created any resources inside of Azure.

Define a composite resource

The Composition that was just created limited which composite resources can use that template.

A composite resource is a custom API defined by the platform teams.
A CompositeResourceDefinition defines the schema for a composite resource.

A CompositeResourceDefinition installs the custom API type into Kubernetes and defines what spec keys and values are valid when calling this new custom API.

Before creating a composite resource Crossplane requires a CompositeResourceDefinition.

Tip
CompositeResourceDefinitions are also called XRDs for short.

Just like a Composition the CompositeResourceDefinition is part of the Crossplane API group.

The XRD name is the new API endpoint.

Tip
Crossplane recommends using a plural name for the XRD name.
1apiVersion: apiextensions.crossplane.io/v1
2kind: CompositeResourceDefinition
3metadata:
4  name: xvirtualmachines.custom-api.example.org

The XRD’s spec defines the new custom API.

Define the API endpoint and kind

First, define the new API group.
Next, create the API kind and plural.

1apiVersion: apiextensions.crossplane.io/v1
2kind: CompositeResourceDefinition
3metadata:
4  name: xvirtualmachines.custom-api.example.org
5spec:
6  group: custom-api.example.org
7  names:
8    kind: XVirtualMachine
9    plural: xvirtualmachines
Note

The XRD group matches the composition apiVersion and the XRD kind matches the composition compositeTypeRef.kind.

1kind: Composition
2# Removed for brevity
3spec:
4  compositeTypeRef:
5    apiVersion: custom-api.example.org/v1alpha1
6    kind: XVirtualMachine

Set the API version

In Kubernetes, all API endpoints have a version to show the stability of the API and track revisions.

Apply a version to the XRD with a versions.name. This matches the compositeTypeRef.apiVersion

XRDs require both versions.served and versions.referenceable.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: CompositeResourceDefinition
 3metadata:
 4  name: xvirtualmachines.custom-api.example.org
 5spec:
 6  group: custom-api.example.org
 7  names:
 8    kind: XVirtualMachine
 9    plural: xvirtualmachines
10  versions:
11  - name: v1alpha1
12    served: true
13    referenceable: true
Note
For more information on defining versions in Kubernetes read the API versioning section of the Kubernetes documentation.

Create the API schema

With an API endpoint named, now define the API schema, or what’s allowed inside the spec of the new Kubernetes object.

Note
XRDs follow the Kubernetes CustomResourceDefinition rules for schemas.

Place the API schema under the version.name

The XRD type defines the next lines. They’re always the same.

openAPIV3Schema specifies how the schema gets validated.

Next, the entire API is an object with a property of spec.

The spec is also an object with properties.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: CompositeResourceDefinition
 3# Removed for brevity
 4spec:
 5  # Removed for brevity
 6  versions:
 7  - name: v1alpha1
 8    schema:
 9      openAPIV3Schema:
10        type: object
11        properties:
12          spec:
13            type: object
14            properties:
Tip
For more information on the values allowed in a CompositeResourceDefinition view its schema with kubectl explain xrd

Now, define the custom API. Your custom API continues under the last properties definition in the previous example.

This custom API has only one setting:

  • region - where to deploy the resources, a choice of “EU” or “US”

Users can’t change any other settings of the VM or its network.

Theregion is a string and can match the regular expression that’s oneOf EU or US.

This API requires the setting region.

 1# Removed for brevity
 2# schema.openAPIV3Schema.type.properties.spec
 3properties:
 4  region:
 5    type: string
 6    oneOf:
 7      - pattern: '^EU$'
 8      - pattern: '^US$'
 9required:
10  - region

Enable claims to the API

Tell this XRD to offer a claim by defining the claim API endpoint under the XRD spec.

Tip
Crossplane recommends a Claim kind match the Composite Resource (XR) kind, without the preceding X.
 1apiVersion: apiextensions.crossplane.io/v1
 2kind: CompositeResourceDefinition
 3# Removed for brevity
 4spec:
 5# Removed for brevity
 6  names:
 7    kind: XVirtualMachine
 8    plural: xvirtualmachines
 9  claimNames:
10    kind: VirtualMachine
11    plural: virtualmachines
Note
The Claims section later in this guide discusses claims.

Apply the CompositeResourceDefinition

Apply the complete XRD to your Kubernetes cluster.

 1cat <<EOF | kubectl apply -f -
 2apiVersion: apiextensions.crossplane.io/v1
 3kind: CompositeResourceDefinition
 4metadata:
 5  name: xvirtualmachines.custom-api.example.org
 6spec:
 7  group: custom-api.example.org
 8  names:
 9    kind: XVirtualMachine
10    plural: xvirtualmachines
11  versions:
12  - name: v1alpha1
13    served: true
14    referenceable: true
15    schema:
16      openAPIV3Schema:
17        type: object
18        properties:
19          spec:
20            type: object
21            properties:
22              region:
23                type: string
24                oneOf:
25                  - pattern: '^EU$'
26                  - pattern: '^US$'
27            required:
28              - region
29  claimNames:
30    kind: VirtualMachine
31    plural: virtualmachines
32EOF

Verify Kubernetes created the XRD with kubectl get xrd

1kubectl get xrd
2NAME                                      ESTABLISHED   OFFERED   AGE
3xvirtualmachines.custom-api.example.org   True          True      4s

Create a composite resource

Creating an XRD allows the creation composite resources.

A composite resource uses the custom API created in the XRD.

The XRD maps the composite resource values to the Composition template and creates new managed resources.

Looking at part of the XRD:

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: CompositeResourceDefinition
 3# Removed for brevity
 4spec:
 5  group: custom-api.example.org
 6  names:
 7    kind: XVirtualMachine
 8# Removed for brevity
 9      spec:
10        type: object
11        properties:
12          region:
13            type: string
14            oneOf:
15              - pattern: '^EU$'
16              - pattern: '^US$'

The XRD group becomes the composite resource apiVersion.

The XRD kind is the composite resource kind

The XRD API spec defines the composite resource spec.

The XRD properties section defines the options for the composite resource spec.

The one option is region and it can be either EU or US.

This composite resource uses region: US.

Apply the composite resource

Apply the composite resource to the Kubernetes cluster.

1cat <<EOF | kubectl apply -f -
2apiVersion: custom-api.example.org/v1alpha1
3kind: XVirtualMachine
4metadata:
5  name: my-composite-resource
6spec: 
7  region: "US"
8EOF

Verify the composite resource

Verify Crossplane created the composite resource with kubectl get xvirtualmachine

Tip
It may take up to 10 minutes for Azure to create the Virtual Machine resources.
1kubectl get xvirtualmachine
2NAME                    SYNCED   READY   COMPOSITION                             AGE
3my-composite-resource   True     True    crossplane-quickstart-vm-with-network   5m2s
Tip
Use kubectl get <kind> to view a specific kind of composite resource.
View all composite resources with kubectl get composite.

Both SYNCED and READY are True when Crossplane created the Azure resources.

Now look at the linuxvirtualmachine and networkinterface managed resources with kubectl get linuxvirtualmachine and kubectl get networkinterface.

1kubectl get linuxvirtualmachine
2NAME                          READY   SYNCED   EXTERNAL-NAME                 AGE
3my-composite-resource-w564c   True    True     my-composite-resource-w564c   8m33s
1kubectl get networkinterface
2NAME                          READY   SYNCED   EXTERNAL-NAME                 AGE
3my-composite-resource-72ft8   True    True     my-composite-resource-72ft8   8m54s

The composite resource automatically generated the managed resources.

Using kubectl describe on a managed resource shows the Owner References is the composite resource.

1 kubectl describe linuxvirtualmachine | grep "Owner References" -A5
2  Owner References:
3    API Version:           custom-api.example.org/v1alpha1
4    Block Owner Deletion:  true
5    Controller:            true
6    Kind:                  XVirtualMachine
7    Name:                  my-composite-resource

Each composite resource creates and owns a unique set of managed resources. If you create a second composite resource Crossplane creates a new LinuxVirtualMachine and new networking resources.

1cat <<EOF | kubectl apply -f -
2apiVersion: custom-api.example.org/v1alpha1
3kind: XVirtualMachine
4metadata:
5  name: my-second-composite-resource
6spec: 
7  region: "US"
8EOF

Again, use kubectl get xvirtualmachine to view both composite resources.

1kubectl get xvirtualmachine
2NAME                           SYNCED   READY   COMPOSITION                             AGE
3my-composite-resource          True     True    crossplane-quickstart-vm-with-network   15m
4my-second-composite-resource   True     True    crossplane-quickstart-vm-with-network   4m15s

And see there are two linuxvirtualmachine and two networkinterface managed resources.

1kubectl get linuxvirtualmachine
2NAME                                 READY   SYNCED   EXTERNAL-NAME                        AGE
3my-composite-resource-w564c          True    True     my-composite-resource-w564c          16m
4my-second-composite-resource-s92lw   True    True     my-second-composite-resource-s92lw   5m8s
1kubectl get networkinterface
2NAME                                 READY   SYNCED   EXTERNAL-NAME                        AGE
3my-composite-resource-72ft8          True    True     my-composite-resource-72ft8          16m
4my-second-composite-resource-wcnnv   True    True     my-second-composite-resource-wcnnv   5m21s

Delete the composite resources

Because the composite resource is the Owner of the managed resources, when Crossplane deletes the composite resource, it also deletes the managed resources automatically.

Delete the new composite resource with kubectl delete xvirtualmachine.

Tip
Delete a specific composite resource with kubectl delete <kind> or kubectl delete composite.

Delete the second composition

1kubectl delete xvirtualmachine my-second-composite-resource
Note
It may take up to five minutes before Crossplane finishes deleting resources.

Now only one virtual machine and network interface exist.

1kubectl get linuxvirtualmachines
2NAME                          READY   SYNCED   EXTERNAL-NAME                 AGE
3my-composite-resource-w564c   True    True     my-composite-resource-w564c   28m
1kubectl get networkinterface
2NAME                          READY   SYNCED   EXTERNAL-NAME                 AGE
3my-composite-resource-72ft8   True    True     my-composite-resource-72ft8   29m

Delete the other composite resource to remove the last linuxvirtualmachines and networkinterface managed resources.

1kubectl delete xvirtualmachine my-composite-resource

Composite resources are great for creating one or more related resources against a template, but all composite resources exist at the Kubernetes “cluster level.” There’s no isolation between composite resources. Crossplane uses Claims to create resources with namespace isolation.

Create a claim

Claims, just like composite resources use the custom API defined in the XRD. Unlike a composite resource, Crossplane can create Claims in a namespace.

Create a new Kubernetes namespace

Create a new namespace with kubectl create namespace.

1kubectl create namespace test

Look at the XRD to see the parameters for the Claim. A Claim uses the same group a composite resource uses but a different kind.

1apiVersion: apiextensions.crossplane.io/v1
2kind: CompositeResourceDefinition
3# Removed for brevity
4spec:
5# Removed for brevity
6  group: custom-api.example.org
7  claimNames:
8    kind: VirtualMachine
9    plural: virtualmachines

Like the composite resource, create a new object with the custom-api.example.org API endpoint.

The XRD claimNames.kind defines the kind.

The spec uses the same API options as the composite resource.

Apply the claim

Apply the claim to your Kubernetes cluster.

1cat <<EOF | kubectl apply -f -
2apiVersion: custom-api.example.org/v1alpha1
3kind: VirtualMachine
4metadata:
5  name: claimed-virtualmachine
6  namespace: test
7spec:
8  region: "US"
9EOF

Verify the claim

Verify Crossplane created the claim with kubectl get virtualmachine in the test namespace.

Tip
View claims with kubectl get <kind> or use kubectl get claim to view all Claims.
1kubectl get virtualmachine -n test
2NAME                     SYNCED   READY   CONNECTION-SECRET   AGE
3claimed-virtualmachine   True     True                        3m40s

When Crossplane creates a Claim, a unique composite resource is also created. View the new composite resource with kubectl get xvirtualmachine.

1kubectl get xvirtualmachine
2NAME                           SYNCED   READY   COMPOSITION                             AGE
3claimed-virtualmachine-cw6cv   True     True    crossplane-quickstart-vm-with-network   3m57s

The composite resource exists at the “cluster scope” while the Claim exists at the “namespace scope.”

Create a second namespace and a second claim.

 1kubectl create namespace test2
 2cat <<EOF | kubectl apply -f -
 3apiVersion: custom-api.example.org/v1alpha1
 4kind: VirtualMachine
 5metadata:
 6  name: claimed-virtualmachine
 7  namespace: test2
 8spec:
 9  region: "US"
10EOF

View the claims in all namespaces with kubectl get virtualmachine -A

1kubectl get virtualmachine -A
2NAMESPACE   NAME                     SYNCED   READY   CONNECTION-SECRET   AGE
3test        claimed-virtualmachine   True     True                        12m
4test2       claimed-virtualmachine   True     True                        7m35s

Now look at the composite resources at the cluster scope.

1kubectl get xvirtualmachine
2NAME                           SYNCED   READY   COMPOSITION                             AGE
3claimed-virtualmachine-7jth5   True     True    crossplane-quickstart-vm-with-network   7m53s
4claimed-virtualmachine-cw6cv   True     True    crossplane-quickstart-vm-with-network   12m

Crossplane created a second composite resource for the second Claim.

Looking at the virtual machines and network interfaces shows two of each resource, one for each claim.

1kubectl get linuxvirtualmachines
2NAME                                 READY   SYNCED   EXTERNAL-NAME                        AGE
3claimed-virtualmachine-7jth5-v2gsh   True    True     claimed-virtualmachine-7jth5-v2gsh   8m10s
4claimed-virtualmachine-cw6cv-w8v65   True    True     claimed-virtualmachine-cw6cv-w8v65   13m
1kubectl get networkinterface
2NAME                                 READY   SYNCED   EXTERNAL-NAME                        AGE
3claimed-virtualmachine-7jth5-hj657   True    True     claimed-virtualmachine-7jth5-hj657   8m44s
4claimed-virtualmachine-cw6cv-f9z4f   True    True     claimed-virtualmachine-cw6cv-f9z4f   13m

Delete the claims

Removing the claims removes the composite resources and the associated managed resources.

1kubectl delete virtualmachine claimed-virtualmachine -n test
2kubectl delete virtualmachine claimed-virtualmachine -n test2

Verify Crossplane removed all the managed resources.

1kubectl get linuxvirtualmachines
2No resources found
1kubectl get networkinterface
2No resources found

Claims are powerful tools to give users resources in their own isolated namespace. But these examples haven’t shown how the custom API can change the settings defined in the Composition. This composition patching applies the API settings when creating resources. Part 3 of this guide covers composition patches and making all this configuration portable in Crossplane Packages.

Next steps